需求中需要用到Element UI的 CascaderPanel组件,并且支持多选,定制化需求,比如某节点被选择,等价于该节点下面所有子节点都被选择, CascaderPanel组件返回的选择数据为选择的所有节点,需要过滤到只返回到最上方被选中的层级。如图所示:
(1)el-cascader-panel组件基本使用
<el-cascader-panel ref="test" :options="myOptions" @change="handNodeChange('test')" v-model="myOptionsSelectedAreas"
:props="{ multiple: true }">
(2)过滤所有节点,过滤方法:!(item.parent && item.parent.checked),即排除掉父节点存在且被选中的节点,得到过滤后的节点:
// 监听级联组件数据变化,隐藏父组件选择状态下的子组件。
handNodeChange(value) {
let checkedNodeList = this.$refs[value].getCheckedNodes();
checkedNodeList = checkedNodeList.filter(item => {
return !(item.parent && item.parent.checked);
});
this[value] = checkedNodeList;
this.myOptionsStandardSelectedAreas = [];
checkedNodeList.forEach(item => {
this.myOptionsStandardSelectedAreas.push(item.path.join('-'));
});
},
(3)坑:最后一级即叶子结点,也有children只不过children=[],这就导致组件无法确定最后一级,所以无法触发change事件。把叶子节点的children删除即可(该坑在Element Plus中测试已没有)。
// 遍历得到需要的树结构
dealNodeTree(node) {
if (!node) {
return null;
}
let temNode = this.changeNode(node);
if (temNode.children) {
// 处理children字段
temNode.children = temNode.children.map(item => {
return this.dealNodeTree(item);
});
}
return temNode;
},
(4)服务器返回的字符串,或者选中数组直到选中节点最高父级,需要获取所有选中的子节点,才能让级联组件正常显示。
dfs对根节点进行深度遍历,获取所有路径,存到全路径列表中,和最高级父节点进行匹配,显示匹配的节点即可。
getAllPath(node, path = []) {
if (!node) {
return null; // 如果为空节点则返回null
}
const currentVal = node.value; // 当前节点值
path.push(currentVal); // 将当前节点值添加到路径数组中
if (!node.children || node.children.length === 0) {
// console.log('路径:', path); // 输出完整路径
this.myResult.push(path);
} else {
for (let i = 0; i < node.children.length; i++) {
this.getAllPath(node.children[i], [...path]); // 对每个子节点进行递归调用
}
}
// path.pop(); // 移除最后一个元素,因为已经处理过该节点了
},