产品经理提出了希望选中父级后自动选中子级,选中子级反而不希望选中父级
elementUI的级联选择器只支持严格的父子关联,后面借助网上资料在原有的基础上进行改良
实现的大体思路:取消严格的父子关联,然后手动处理选中父级后选中子级
代码:
// 实现父关联子,子不关联父
cascaderChange(val) {
setTimeout(() => {
const checkedNodes = this.$refs.cascader.getCheckedNodes();
if (checkedNodes.length) {
this.lastCheckedNodes = this.lastCheckedNodes || [];
// 获取差异值,差异值就是选中/取消选中的值
const diffList = this.findMissingInBoth(checkedNodes, this.lastCheckedNodes);
// 选中/取消选中 操作
const isChecked = val.length > this.lastCheckedNodes?.length;
// 对差异值进行递归
this.recursion(diffList, isChecked);
// 更新视图
this.$refs.cascader.$refs.panel.calculateMultiCheckedValue();
}
// 保存上一次的值,用来获取差异值以及确认操作类型
this.lastCheckedNodes = checkedNodes;
});
},
// 递归处理子级是否选中
recursion(list = [], bool) {
list.forEach((item) => {
item.checked = bool;
if (item.children?.length) {
this.recursion(item.children, bool);
}
});
},
// 双方找对方没有的集合
findMissingInBoth(arr1, arr2) {
const valuesInArr1 = arr1.map((item) => item.value); // 提取arr1中集合对象的value属性
const valuesInArr2 = arr2.map((item) => item.value); // 提取arr2中集合对象的value属性
const missingInArr1 = arr1.filter((item) => !valuesInArr2.includes(item.value)); // 在arr1中而不在arr2中的集合对象
const missingInArr2 = arr2.filter((item) => !valuesInArr1.includes(item.value)); // 在arr2中而不在arr1中的集合对象
return [...missingInArr1, ...missingInArr2];
},
<el-cascader
ref="cascader"
v-model="formData.relatedRecruit"
filterable
placeholder="请选择"
:options="orgList"
:props="{
value: 'value',
label: 'label',
checkStrictly: true,
emitPath: false,
multiple: true
}"
:show-all-levels="false"
@change="cascaderChange"
>
</el-cascader>
如果需要回显的话得在created里初始化lastCheckedNodes(表单赋值后)
created() {
setTimeout(() => {
// 回显时lastCheckedNodes的初始化,需要异步获取选中节点
this.lastCheckedNodes = this.$refs.cascader.getCheckedNodes();
});
},
ps:只是实现了功能,有些地方还存在瑕疵,如change方法会触发两次等