el-tree基础的树形节点设置节点不能选中高亮出来,对已经选中的节点设置disabled,对当前节点刚选中后设置禁用disabled
一、 el-tree基础的树形节点设置节点不能选中高亮出来
需求
我们使用element-ui或者element-plus的时候会遇到树形控件的使用,我们使用树形控件会限制有的节点不让选中和高亮出来,这个时候需要我们做限制。在实现中我们发现了element-ui和element-plus的时候他们实现的方式还是有点区别的,我们就简单来实现一下。
实现效果如下:
vue2+element-ui
发现element-ui中更改current-node-key值无效,最后用this.$refs.tree.setCurrentKey方法实现了
实现的思路:
- el-tree加上highlight-current属性,高亮当前选中节点
- ref="tree"绑定组件
- el-tree的点击事件@node-click中判断是有子元素的节点,则找到上次高亮的节点,让它继续选中高亮,思路是通过node-key="id"和this.$refs.tree.setCurrentKey方法
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
highlight-current
ref="tree"
node-key="id"
>
handleNodeClick(data, node) {
//设置不能选中的节点
if (data.disabled) {
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(this.currentNodeKey);
});
return;
}
this.currentNodeKey = data.id;
}
vue3+element-plus
发现element-plus中更改current-node-key值是有效的,通过这个属性实现
思路:
- el-tree加上highlight-current属性,高亮当前选中节点
- el-tree的点击事件@node-click中判断有子元素的节点不能选中高亮,核心代码node.isCurrent = false,让当前节点取消选中
- 这时需要找到上次高亮的节点,让它继续选中高亮,思路是通过node-key与current-node-key属性
<template>
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
highlight-current
node-key="id"
:current-node-key="currentNodeKey"
default-expand-all
:expand-on-click-node="false"/>
</template>
<script lang="ts" setup>
import type Node from 'element-plus/es/components/tree/src/model/node'
import { ref, nextTick } from "vue"
interface Tree {
label: string
children?: Tree[]
}
const currentNodeKey = ref("")
const treeId = ref("")
const handleNodeClick = (data: Tree, node: Node) => {
// 有子元素的节点,不能选中
if (data.children.length) {
node.isCurrent = false
// 值更改,触发watch
currentNodeKey.value = ""
// 还原之前的高亮节点
nextTick(() => {
currentNodeKey.value = treeId.value
})
return
}
treeId.value = data.id
// 点击树节点执行的代码
...
}
const data: Tree[] = [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
},
],
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
},
]
const defaultProps = {
children: 'children',
label: 'label',
}
</script>
二、 对已经选中的节点设置disabled
el-tree 动态渲染值对已知节点disabled
实现思路:
- 从后台动态获取的树的数据
- 项目需求要把其中的某一个节点设置为禁用
- 在data中配置el-tree的props
- 我这里是已知节点的数据 判断节点id来设置disabled
<el-tree
ref="tree"
:data="menuData"
show-checkbox
node-key="node_id"
:props="defaultProps2"
:default-checked-keys="checkedId"
/>
defaultProps2: {
children: 'children',
label: 'name',
disabled: function(data, node) {
// 禁用回收站选项
if (data.level === 3) {
return true
}
}
}
三、对当前节点刚选中后设置禁用disabled(设置多复选框为不可编辑,只有选中后就不能编辑操作)
实现效果如下:
具体操作如下:
html
<template>
<div class="tree3">
<span>设置多选复选框为不可编辑,只要选中就不可编辑</span>
<div style="margin-left: 600px;width:100%">
<el-tree
:data="data3"
ref="tree"
show-checkbox
node-key="id"
:check-on-click-node="checkNodeFlag"
:default-expanded-keys="[2, 3]"
@check-change="handleCheckChageFun"
@check="handleCheckFun"
>
</el-tree>
</div>
<!-- :default-checked-keys="defaultCheckedKeys" -->
</div>
</template>
js
data() {
return {
checkNodeFlag:false,
currNodeId:'',//当前选中nodeId
defaultCheckedKeys:[],
data3: [{
id: 1,
label: '一级 2',
disabled:false,
children: [{
id: 3,
label: '二级 2-1',disabled:false
}, {
id: 2,
label: '二级 2-2',
disabled:false
},
{id: 4, label: '2级 4',disabled:false},
{id: 5, label: '2级 5',disabled:false},
{id: 6, label: '2级 6',disabled:false},
{id: 7, label: '2级 7',disabled:false},
{id: 8, label: '2级 8',disabled:false},
{id: 9, label: '2级 9',disabled:false},
{id: 10, label: '2级 10',disabled:false},
{id: 11, label: '2级 11',disabled:false},
{id: 12, label: '2级 12',disabled:false},
{id: 13, label: '2级 13',disabled:false},
{id: 14, label: '2级 14',disabled:false},
{id: 15, label: '2级 15',disabled:false},
{id: 16, label: '2级 16',disabled:false},
{id: 17, label: '2级 17',disabled:false},
{id: 18, label: '2级 18',disabled:false},
]
}],
disableData:this.data3,
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods:{
handleCheckChageFun(currNode){
console.log("hanleCheckChageFun---");
},
handleCheckFun(currNode){
this.currNodeId = currNode.id;
this.defaultCheckedKeys= null
this.dealTreeOnceChecked(this.data3)
},
dealTreeOnceChecked(arrMenus){
arrMenus === undefined ? arrMenus=[]:''
if(arrMenus.length > 0){
//let disarr = [];
arrMenus.forEach(item => {
let arrChildren = item.children
if(arrChildren !== null) this.dealTreeOnceChecked(arrChildren)
item.id === this.currNodeId ? item.disabled = true :'';
})
}
}
}