需求为使用弹窗选择区域,弹窗左侧为待选区,右侧会展示当前已选中项,也是树形控件展示,如果打开弹窗时上次有选中数据,需要展示出来并勾选相应树形节点
1、html及配置项、数据源部分
由于需求中有需要主动设置选中项,所以需要设置node-key项
<el-tree
ref="tree" :data="data"
node-key="areaCode"
:props="defaultProps" show-checkbox render-after-expand
@check-change="handleCheckChange">
<span class="custom-tree-node" slot-scope="{ node }">
<span>{{ node.label }}</span>
</span>
</el-tree>
数据源等:
data: [ // 树形控件数据源
{
areaCode: "1",
areaName: "中国",
level: 0,
parentAreaCode: "0",
path: "0",
subList: [
{
areaCode: "11",
areaName: "中国大陆",
subList: [
{
areaCode: "111",
areaName: "华北大区"
}
]
},
{
areaCode: "12",
areaName: "香港特别行政区",
},
]
}
],
dataSelected: [], // 被选中得右侧数据
defaultProps: { // 用来自定义当前树形组件节点显示以及子节点数组的字段名
children: 'subList',
label: 'areaName'
},
drawerData: [], // 上次选中的值
2、选中及相关操作
控件中选中节点变化会触发check-change事件,在此事件中,拿到被选中项给右侧展示
此处需要注意的是,getCheckedNodes拿到的数据有可能有重复项,需要先去重
handleCheckChange() {
// 通过getCheckedNodes拿到被选中的数据之后,判断path和areaCode去重,得到最终无重复的树形结构
let arr = JSON.parse(JSON.stringify(this.$refs.tree.getCheckedNodes()))
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++){
// 如果外层arr[i]的name等于内层arr[i]的name,splice方法删除内层arr[i]
if ( arr[j].path.indexOf(arr[i].areaCode) != -1) {
arr.splice(j,1);
j--;
}
}
}
this.dataSelected = arr
},
3、初始打开弹窗时设置默认勾选节点
如果上一次有保存选中值,则再次打开需要把上次选中节点默认勾选,使用setCheckedNodes方法即可
this.$nextTick(() => { // 如果上次有选过,需要把选中的继续改为选中状态
if (!this.$refs.tree) return // 如果找不到树形控件,则不继续执行,避免报错
this.$refs.tree.setCheckedNodes(this.drawerData)
})
效果