需求
选中父节点,子节点默认全选,取消一个子节点,那么这个子节点的所有父节点都取消掉选中状态,但是其兄弟节点不会受影响。
场景
场景一: 点击‘你好’,所有子节点全选中
场景二: 点击‘再见’,取消‘再见’和‘你好’节点
场景三:点击‘3’,最下层节点‘4’也会被选中。取消最下层节点‘4’,节点‘3’也会被取消
代码
以下为完整代码:
<template>
<div class="custom-tree-container">
<div class="block">
<p>使用 scoped slot</p>
<el-tree
:data="treeList"
ref="tree"
@check="clickDeal"
:check-strictly="true"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false"
@check-change="checkChange"
:props="leftProps"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
</span>
</el-tree>
</div>
</div>
</template>
<script>
export default {
props: {
treeList: {
type: Array,
default() {
return []
}
}
},
name: 'treeTest',
components: {},
data() {
return {
leftProps: {
label: 'name'
},
isClickSelected: false
}
},
methods: {
checkChange(obj, isChecked, isChildChecked) {
// 取消,子节点只要有一个被取消父节点就被取消
if (!isChecked) {
this.$refs.tree.setChecked(obj.p_id, false)
}
},
clickDeal(currentObj, treeStatus) {
// 用于:父子节点严格互不关联时,父节点勾选变化时通知子节点同步变化,实现单向关联。
let selected = treeStatus.checkedKeys.indexOf(currentObj.id) // -1未选中
this.isClickSelected = selected
// 选中
if (selected !== -1) {
// 子节点只要被选中父节点就被选中
this.selectedChildren(currentObj)
// 统一处理子节点为相同的勾选状态
this.uniteChildSame(currentObj, true)
} else {
// 未选中 处理子节点全部未选中
if (currentObj.children && currentObj.children.length !== 0) {
this.uniteChildSame(currentObj, false)
}
}
},
// 统一处理子节点为相同的勾选状态
uniteChildSame(treeList, isSelected) {
this.$refs.tree.setChecked(treeList.id, isSelected)
let childLen = treeList.children ? treeList.children.length : 0
if (childLen) {
for (let i = 0; i < childLen; i++) {
this.uniteChildSame(treeList.children[i], isSelected)
}
}
},
// 统一处理子节点为选中
selectedChildren(currentObj) {
let currentNode = this.$refs.tree.getNode(currentObj)
currentNode.childNodes.map(item => {
if (item.key !== undefined) {
this.$refs.tree.setChecked(item, true)
this.selectedChildren(item)
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
数据结构
这是后端返回的数据的结构: