el-tree动态联动选择

el-tree为我们封装了很多功能,基本可以绝大部分日常需求,其中check-strictly属性,可以方便的在选择节点的时候切换不同的勾选策略,但是不管怎样,需求总会例外,不会有完美的实现能满足所有需求。

# 需求

为了更灵活的勾选需要的节点,我们遇到一个产品需求,需要动态的在父子节点关联和不关联中切换,关联策略仅影响后操作的节点。

# 解决方案

需求缕清楚其实并不麻烦,我们只要根据el-tree的api做一次封装,主要思路:

提示

联动属性check-strictly 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false

  • el-tree的属性check-strictly设置为false,并在data中定义checkStrictly,记录当前策略,并便于切换修改
  • 监听节点check的事件,根据当前策略收集checkedKeys
    1. 父子联动的情况下,使用el-tree的默认策略,check方法不做处理
    2. 不联动情况下,获取节点下所有后代节点;根据选中和取消选择两种情况(选中取交集,取消取差集合)
  • 使用setCheckedKeys方案勾选收集到的keys

# 关键代码

主要在check方法中修改

check( data, node ){
	if(this.checkStrictly){
		//联动
        // 获取后代节点
		const children = this.toList([data]).map(item => item.id);
		if(node.checkedKeys.includes(data.id)){
			// 选择当前-自动勾选子节点 取交集
			this.$refs.tree.setCheckedKeys(children.concat(this.checkedKeys));
		} else{
			// 取消选择-取消勾选子节点 取差集
			const diff = this.checkedKeys.concat(children).filter(v => !children.includes(v));
			this.$refs.tree.setCheckedKeys(diff);
		}
	}
	this.checkedKeys = this.$refs.tree.getCheckedKeys();
}

# 完整demo

已选:[]
一级 1
二级 1-1
三级 1-1-1
三级 1-1-2
一级 2
二级 2-1
二级 2-2
一级 3
二级 3-1
二级 3-2
<template>
	<div>
		<div>
			<span><el-checkbox v-model="checkStrictly">父子关联</el-checkbox></span>
			<sapn>已选:{{checkedKeys}}</sapn>
		</div>
		<el-tree :data="data" show-checkbox default-expand-all
		         node-key="id"
		         ref="tree"
		         check-strictly
		         @check="check"
		         highlight-current>
		</el-tree>
	</div>
</template>
<script>
export default {
	name: 'TreeDemo',
	data(){
		return {
			data: [{
				id: 1,
				label: '一级 1',
				children: [{
					id: 4,
					label: '二级 1-1',
					children: [{id: 9, label: '三级 1-1-1'}, {id: 10, label: '三级 1-1-2'}]
				}]
			}, {
				id: 2,
				label: '一级 2',
				children: [{id: 5, label: '二级 2-1'}, {id: 6, label: '二级 2-2'}]
			}, {
				id: 3,
				label: '一级 3',
				children: [{id: 7, label: '二级 3-1'}, {id: 8, label: '二级 3-2'}]
			}],
			checkedKeys: [],
			checkStrictly: true,
		};
	},
	methods: {
		check( data, node ){
			if(this.checkStrictly){
				//联动
				const children = this.toList([data]).map(item => item.id);
				if(node.checkedKeys.includes(data.id)){
					// 选择当前-自动勾选子节点 取交集
					this.$refs.tree.setCheckedKeys(children.concat(this.checkedKeys));
				} else{
					// 取消选择-取消勾选子节点 取差集
					const diff = this.checkedKeys.concat(children).filter(v => !children.includes(v));
					this.$refs.tree.setCheckedKeys(diff);
				}
			}
			this.checkedKeys = this.$refs.tree.getCheckedKeys();
		},
		toList( tree ){
			let tmp = [];
			tree.map(child => {
				if(child.children && child.children.length){
					tmp = [...tmp, ...this.toList(child.children)];
				}
				tmp.push(child);
			});
			return tmp;
		}
	},

};
</script>
Show Copy
最近更新
01
echarts扇形模拟镜头焦距与可视化角度示意图
03-10
02
vite插件钩子
03-02
03
vite的依赖预构建
02-13
更多文章>