一、用到的组件

[Table 表格],用于展示数据;[Tree 树形控件]用于编辑表头的展示与否及表头的展示顺序。

二、实现

1、Table 组件

将 [el-table-column] 的各项内容放在一个数组中,这个数组也是用来生成 [Tree 树形控件] 的控件,在实际的Table 中有些项可能会用到 template,所以在该数组中标识出来,我们需要的 [Tree 树形控件] 控件是没有children的,所以该数组的结构类似于:

tableItem: [
  {
     nodeKey: 1,	// tree 控件的唯一标识
     label: '名称一',	// el-table-column 的名字
     width: '240',	// el-table-column 的宽度
     keyProp: 'name1',	// el-table-column 的数据名
     template: true	// 是否使用 template 
   }
]    

数据获取到以后,通过循环 ( 注意:不要使用直接使用 tableItem 这个数组, 将这个数组深度拷贝出来 赋值给一个新的数组, 后面会讲到原因 )渲染出默认的 Table 的结构。

2、Tree 组件

<el-tree
   :data="tableItem"
      show-checkbox
      node-key="nodeKey"
      :default-checked-keys="defaultCheckedKeys"	// 默认选中项,可将上一步数组里面的 nodeKey 放在 defaultCheckedKeys 数组中
      :props="defaultProps"
      :allow-drop="allowDrop"
      :allow-drag="allowDrag"
      draggable
      @check="itemNodeCheck"
      @node-drag-end="handleDragEnd"
      ref="itemTree"
    >
</el-tree>

Tree 组件拖拽配置

// 不允许放入内部
allowDrop(draggingNode, dropNode, type) {
	return type !== 'inner'
},

// 允许拖拽
allowDrag(draggingNode) {
	  return true
}

这样配置后,tree 拖拽后 被拖拽的item 的 checked 将变成false,所以我们需要拖拽之前记录下 所有的 checked-keys, 拖拽后在设置回来:

// Tree check 变换时做 checked-keys 的记录
itemNodeCheck(item, tree) {
	this.defaultCheckedKeys = tree.checkedKeys
}

// 拖拽后将 Tree 的 checked-keys 设置回拖拽前的
handleDragEnd(draggingNode, dropNode, dropType, ev) {
	this.$refs.itemTree.setCheckedKeys(this.defaultCheckedKeys)
}

三、遇到的问题及解决思路

1、在 Tree 中编辑时, Table会实时变。

2.1中提到了,将 tableItem 深度拷贝出来 赋值给一个新的数组,来渲染 Table,就不会实时变了, 编辑完成后通过点击一个确认按钮来重新 渲染 Table。

1、Table 中 el-table-column 的顺序与Tree中的不一致。

这个也是在实现中卡的时间最长的地方,查了很多 什么 v-if 、 doLayout 都试了还是不行。最后用了一个笨办法算是把效果实现了: 点击确认按钮后 把 渲染 Table 那个数组 清空, setTimeout 一下 再赋值。

Logo

前往低代码交流专区

更多推荐