el-tree 父子节点勾选框半关联
问题
有个节点带 checkbox 的 el-tree
父子节点需要半关联,即:
1.勾选父节点,子节点不会被勾选;
2.但是勾选子节点,父节点会被勾选。
解决
第一步:实现父子节点不相互关联
子组件:
父组件:
第二步:实现勾选子节点,父节点会被勾选
关键问题是如何勾选某个节点。
- 方式一:
setChecked()
通过父节点的nodeKey
或者data
;- 方式二:找到父节点的
node
,设置checked = true
方式一(推荐):监听每个节点,若被勾选,则勾选它的父节点。即:
通过 check-change
判断:若当前节点被勾选,则勾选它的父节点。
子组件 MenuTree:
@check-change="(data, checked, indeterminate) => $emit('custom-check-change', {data, checked, indeterminate})"
// 通过 key / data 设置某个节点的勾选状态 // key/data, checked, deep
setChecked(key, checked, deep) {
this.$refs.tree.setChecked(key, checked, deep);
},
父组件:
@custom-check-change="customCheckChange"
// 自定义树节点的 check-change 事件
customCheckChange(argus) {
const { data, checked } = argus
// 若当前节点勾选,则也勾选父节点
if (!data.pid) return
if (checked) {
// nodeKey 为 el-tree 的 node-key,默认为 'id'
const { nodeKey, nodeData, setChecked } = this.$refs['menuTree']
if (nodeKey === 'id') {
setChecked(data.pid, true)
} else {
// 树形扁平化 // this.extractTree() 为封装的公共方法
const flatNodeData = this.extractTree(nodeData,'children')
const target = flatNodeData.find(ele => ele.id == data.pid)
if (target) {
setChecked(target[nodeKey], true)
}
}
}
}
方式二:
分析
查找官方文档发现:el-tree
的 自定义事件的参数中包含 node
且较为合适的只有 node-click
事件。可以通过它找到父节点的 node
并设置checked = true
。
但是有个问题:node-click
事件仅在点击节点名称时才会触发,如果是点击复选框,则不会触发。
解决:给节点名称前设置伪元素,伪元素覆盖原来的复选框,点击复选框实际上是点击了伪元素。
代码
子组件
@node-click="handleNodeClick"
/* 功能:点击复选框,相当于点击节点这一行 */
// 节点名 // custom-tree-node 是自定义节点的类名,如果没有自定义节点,则用 el-tree-node__label
::v-deep .custom-tree-node{
position: relative;
}
// 节点名前的复选框:伪元素,绝对定位;点击伪元素触发的是主元素的 click 事件
::v-deep .custom-tree-node:before{
content:'';
width:20px;
height: 20px;
display: block;
position:absolute;
top:0px;
left:-24px;
z-index:999;
}
// 被伪元素覆盖的原来的复选框
::v-deep .el-checkbox__inner{
top:0;
}
效果
参考链接
本文来自博客园,作者:shayloyuki,转载请注明原文链接:https://www.cnblogs.com/shayloyuki/p/16895462.html
posted on 2022-11-16 12:06 shayloyuki 阅读(1184) 评论(0) 编辑 收藏 举报