因为element组件库中Tree 树形控件自带穿梭框无法满足业务需求,所以利用el-tree和el-table结合的方式自定义穿梭框。
效果图
该功能满足左侧树形控件的整体选中和子集单独选中和取消效果,对应右侧列表的展示和隐藏以及自定义的删除列表项关联左侧树形控件自动取消功能。
代码如下
<template>
<!-- 自定义树形穿梭框组件、理论上左右均可选择是否为树形结构,目前固定为左侧树形、右侧无层级结构 -->
<div class="tree-transfer">
<!-- 穿梭框左侧 -->
<div class="tree-transfer-left">
<el-tree
ref="treeLeft"
class="treeitems"
:data="Left"
show-checkbox
node-key="Id"
:props="defaultProps"
default-expand-all
@check-change="handleCheck"
/>
</div>
<!-- 穿梭框右侧 -->
<div class="tree-transfer-right">
<el-table
:data="tableData"
style="width: 100%"
:header-cell-style="{
background: '#E5ECF0',
}"
>
<el-table-column type="index" label="序号" align="center" width="100" />
<el-table-column prop="Name" label="字段名称" align="center" />
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="deleteRow(scope.row)">移除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
注意点:el-tree组件上node-key需要将其设置为当前选中节点的一个字段,该字段在每个节点上是唯一存在的。
左侧树形控件数据结构如下:
Left: [{
Id: 1,
Name: '一级 1',
children: [
{
Id: 11,
Name: '一级 1-1',
children: [{
Id: 111,
Name: '一级 1-1-1',
children: []
}, {
Id: 112,
Name: '一级 1-1-2',
children: []
}]
}
]
}, {
Id: 2,
Name: '二级 2',
children: [{
Id: 21,
Name: '二级 2-1',
children: [{
Id: 211,
Name: '二级 2-1-1',
children: []
}]
}, {
Id: 22,
Name: '二级 2-2',
children: []
}]
}, {
Id: 3,
Name: '三级 3',
children: [{
Id: 31,
Name: '三级 3-1',
children: []
}, {
Id: 32,
Name: '三级 3-2',
children: [{
Id: 321,
Name: '三级 3-2-1',
children: []
}, {
Id: 322,
Name: '三级 3-2-2',
children: []
}]
}]
}]
逻辑代码如下:
data() {
return {
tableData: [],
defaultProps: {
children: 'children',
label: 'dataItemName'
}
};
},
methods: {
// 复选框点击事件
handleCheck() {
const nodes = this.$refs.treeLeft.getCheckedNodes().concat(this.$refs.treeLeft.getHalfCheckedNodes());
if (nodes.length !== 0) {
const filterNodes = nodes.filter(node => { // 过滤出子节点,也就是不含childred字段的节点数据
return node.children.length === 0;
});
this.tableData = filterNodes;// 赋值给表格数据
}
},
// 删除按钮
deleteRow(rows) {
this.tableData.forEach((item, index) => { // 从列表中删除当前数据列
if (item.dataItemId === rows.dataItemId) {
this.tableData.splice(index, 1);
}
});
this.$refs.treeLeft.setCheckedNodes(this.tableData);// 取消左侧复选框的选中状态
}
}
注: 该逻辑只包括tree树形数据结构及展示和右侧列表联动效果,无对右侧列表数据有无校验内容。如有需求请留言。