需求:选中父级,各个层级的子级都要选中,取消父级,下面所有子级取消选中;选中子级的时候,父级不选,取消子级,父级不取消。
思路:设置父子级完全不关联,checkStrictly属性设置为true,然后通过选择父级,手动将下面子级全部选中,反之,全部取消。
主要代码:
<template>
<div>
<el-cascader
ref="tree"
v-model="ruleForm.org_list"
size="small"
placeholder="试试搜索"
filterable
style="width: 220px"
clearable
:show-all-levels="false"
:props="{ multiple: true, emitPath: false, checkStrictly: true }"
:options="orgOptions"
/>
</div>
</template>
<script>
import { checkedChildren, cancelChildren } from '@/utils/index'
export default {
data() {
return {
ruleForm: {
org_list: []
},
orgOptions: [],
checkedNode: '' // 保存上次选中的Node节点
}
},
watch: {
'ruleForm.org_list': {
deep: true,
handler(newArr, oldArr) {
if (newArr && newArr.length) {
const current = this.findCurrentDepartment(newArr, oldArr)
if (!current) return
this.$nextTick(() => {
if (current.type === 'checked') {
// 从级联选择器中取出内部的节点数组,找到当前节点
let targetNode = ''
this.checkedNode = this.$refs.tree.checkedNodes // 保存选中的节点, 取消用到
targetNode = this.$refs.tree.checkedNodes.find((item) => {
return item.value === current.value
})
if (targetNode) {
// 递归找出所有子孙节点,并手动勾选
checkedChildren([targetNode])
// 更新视图
this.$refs.tree.$refs.panel.calculateMultiCheckedValue()
}
} else if (current.type === 'cancel') {
// 从级联选择器中取出内部的节点数组,找到当前节点
let targetNode = ''
targetNode = this.checkedNode.find((item) => {
return item.value === current.value
})
// console.log('选中的节点', this.checkedNode)
// console.log('===========', targetNode)
if (targetNode) {
// 递归找出所有子孙节点,并手动取消勾选
cancelChildren([targetNode])
// console.log('修改之后的节点树', cancelChildren([targetNode]))
// 更新视图
this.$refs.tree.$refs.panel.calculateMultiCheckedValue()
}
}
})
}
}
}
},
methods: {
// 判断当前操作是选中还是取消
findCurrentDepartment(newArr, oldArr) {
const catchNewArr = [...newArr]
const catchOldArr = [...oldArr]
if (catchNewArr.length > catchOldArr.length) {
// console.log('为添加')
for (let i = 0; i < catchNewArr.length; i++) {
const targetIndex = catchOldArr.indexOf(catchNewArr[i])
if (targetIndex === -1) {
return {
value: catchNewArr[i],
type: 'checked'
}
}
}
} else {
// console.log('为取消')
// console.log(catchOldArr, catchNewArr)
for (let i = 0; i < catchOldArr.length; i++) {
const targetIndex = catchNewArr.indexOf(catchOldArr[i])
if (targetIndex === -1) {
return {
value: catchOldArr[i],
type: 'cancel'
}
}
}
}
},
},
}
</script>
// utils/index.js
// 处理树节点 选中父 子全部选上
export function checkedChildren(val) {
for (const item of val) {
item.checked = true
if (item.children && item.children.length !== 0) {
checkedChildren(item.children)
}
}
return val
}
// 处理树节点 取消父 子全部取消
export function cancelChildren(val) {
for (const item of val) {
item.checked = false
if (item.children && item.children.length !== 0) {
cancelChildren(item.children)
}
}
return val
}