前言
遇到需求如下:
- 当取消勾选某个节点为按钮时,并且该节点的
同级节点都为按钮时
(此时父级是勾选状态),不管同级节点是否都取消勾选,那么父级不取消勾选。除非手动取消父级勾选(原因是:页面和按钮不构成联动逻辑
) - 当同级节点为
按钮和菜单混合
,或者都为菜单
时,并且同级都取消勾选了,那么父级勾选。
综上,想了下,打算设置element tree 父子不关联,然后手动重写关联逻辑。
代码
<template>
<div>
<el-tree :data="treeData" node-key="id" :props="defaultProps" @check="handleCurrCheck"
:check-strictly="checkStrictly" ref="treeRef" default-expand-all show-checkbox>
</el-tree>
<el-button type="primary" style="margin-top: 20px;" @click="handleTreeChecked">获取当前选中数据</el-button>
</div>
</template>
<script>
/**
* 设置父子不关联。根据业务需求手动重写父子关联逻辑
* type: 1 为按钮 0 为菜单
*/
export default {
data() {
return {
treeData: [
{
id: 1,
label: '一级 1',
children: [
{
id: 4,
label: '二级 1-1',
parentId: 1,
children: [
{
id: 7,
label: '三级 1-1-1',
parentId: 4
},
{
id: 8,
label: '三级 1-1-2',
parentId: 4
}
]
}
]
},
{
id: 2,
label: '一级 2',
children: [
{
id: 5,
label: '按钮 2-1',
type: 1,
parentId: 2
}
]
},
{
id: 3,
label: '一级 3',
children: [
{
id: 6,
label: '按钮 3-1',
type: 1,
parentId: 3
},
{
id: 9,
label: '二级 3-2',
type: 0,
parentId: 3
}
]
}
],
defaultProps: {
children: 'children',
label: 'label'
},
checkStrictly: true,
};
},
methods: {
handleCurrCheck(data) {
let currentNode = this.$refs.treeRef.getNode(data)
if (currentNode.checked) { // 选中
this.recursionParentChecked(currentNode.parent, true) // 该级以上,父级选中
this.recursionChildChecked(currentNode.childNodes, true) // 该级以下,子级全部选中
} else { // 取消
this.recursionChildChecked(currentNode.childNodes, false)// 该级以下,子级全部取消
// if (data.type != 1) { // 是菜单,父级就正常取消
this.recursionParentChecked(currentNode.parent, false, data.type) // 该级以上,父级需要判断
// }
}
},
recursionParentChecked(node, isChecked, type) { // 递归父级
if (node.level != 0) {
if (isChecked) { // 勾选
if (node) {
this.$refs.treeRef.setChecked(node.data, true)
this.recursionParentChecked(node.parent, isChecked)
}
} else { // 取消勾选
if (node && node.childNodes) {
const res = node.childNodes.filter(item => !item.checked)
const isExistMenu = node.childNodes.some(item => !item.data.type)
if (node.childNodes.length == res.length && isExistMenu) { // 子级全部取消了,并且没有菜单,则父级取消勾选状态
this.$refs.treeRef.setChecked(node.data, false)
}
this.recursionParentChecked(node.parent, isChecked, type)
}
}
}
},
recursionChildChecked(node = [], isChecked) { // 递归子级
node.forEach(item => {
this.$refs.treeRef.setChecked(item.data, isChecked)
this.recursionChildChecked(item.childNodes, isChecked)
})
},
handleTreeChecked() {
const res = this.$refs.treeRef.getCheckedKeys()
console.log(res);
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>