el-tree选中数据重组成树

vue+element-ui 实现el-tree选择重新生成一个已选中的值组成新的数据树,效果如下

html 复制代码
<template>
	<div  class="flex">
		<el-tree class="tree-row" :data="list" ref="tree" :props="{children: 'children', label: 'itemCategoryName'}" show-checkbox node-key="id" default-expand-all  @check-change="getChecked">
		</el-tree>
		<el-tree class="tree-row" :data="selectedTreeData"  :props="{children: 'children', label: 'itemCategoryName'}"  node-key="id" default-expand-all   :expand-on-click-node="false">
			<span class="custom-tree-node" slot-scope="{ node, data }">
				<span>{{ node.label }}</span>
				<span>
				<el-button
					type="text"
					size="mini"
					@click="() => remove(node, data)">
					Delete
				</el-button>
				</span>
			</span>
		</el-tree>
	</div>
</template>
<script>
export default {
	data() {
		return {
			list: [
				{
					"id": "4100000000000071",
					"itemCategoryCode": "001",
					"itemCategoryName": "白酒类",
					children: [{
						"id": "41000020000000071",
						"itemCategoryCode": "0012",
						"itemCategoryName": "白酒类2",
						children: [{
							"id": "41000040000000071",
							"itemCategoryCode": "0014",
							"itemCategoryName": "白酒类4",
						},
						{
							"id": "41000050000000071",
							"itemCategoryCode": "0015",
							"itemCategoryName": "白酒类5",
						},
						{
							"id": "41000060000000071",
							"itemCategoryCode": "0016",
							"itemCategoryName": "白酒类6",
						}]
					},
					{
						"id": "41000030000000071",
						"itemCategoryCode": "0013",
						"itemCategoryName": "白酒类3",
					}]
				},
			],
			// selectedIds: ['41000040000000071', "41000060000000071"],
			selectedTreeData:[]
		}
	},
	created() {
	},
	methods: {
		getChecked() {
			this.selectedIds = this.$refs.tree.getCheckedKeys(true);
            this.extractSubtrees();
		},
		extractSubtrees() {
			const subtrees = [];
			for (const id of this.selectedIds) {
				const subtree = this.extractSubtree(this.list, id);
				if (subtree) {
					subtrees.push(subtree);
				}
			}
			this.selectedTreeData = this.mergeSubtrees(subtrees);
		},
		extractSubtree(treeData, targetId) {
			for (const node of treeData) {
				if (node.id === targetId) {
					// return this.cloneAndFilterChildren(node); 可以用这个也可以用下边的方式
					return { ...node };
				}
				if (node.children) {
					const subtree = this.extractSubtree(node.children, targetId);
					if (subtree) {
						// return this.cloneAndFilterChildren({ ...node, children: [subtree] });可以用这个也可以用下边的方式
						return { ...node, children: [subtree] };
					}
				}
			}
			return null;
		},
		cloneAndFilterChildren(node) {
			if (!node.children || node.children.length === 0) {
				return { ...node, children: [] };
			}
			const filteredChildren = node.children
				.map(child => this.cloneAndFilterChildren(child))
				.filter(child => this.selectedIds.includes(child.id) || child.children.length > 0);
			return { ...node, children: filteredChildren };
		},
		mergeSubtrees(subtrees) {
			this.mergedTree = [];
			const idMap = {};

			for (const subtree of subtrees) {
				this.addSubtreeToMergedTree(this.mergedTree, subtree, idMap);
			}

			return this.mergedTree;
		},
		addSubtreeToMergedTree(mergedTree, subtree, idMap) {
			if (!subtree) return;

			const node = { ...subtree, children: [] };

			if (!idMap[node.id]) {
				idMap[node.id] = node;
				mergedTree.push(node);
			} else {
				// Object.assign(idMap[node.id], node);
			}

			if (subtree.children) {
				for (const child of subtree.children) {
					this.addSubtreeToMergedTree(mergedTree[mergedTree.length-1].children, child, idMap);
				}
			}
		},
		remove(node, data) {
			let keys = [];
			this.getRemovedIds(data,keys);
			keys.map(item => {
				this.selectedIds.splice(this.selectedIds.indexOf(item), 1);
			})
			this.$refs.tree.setCheckedKeys(this.selectedIds);
		},
		getRemovedIds(data,keys) {
			if (data.children && data.children.length > 0) {
				data.children.map(item => {
					this.getRemovedIds(item,keys);
				})
			} else {
				keys.push(data.id);
			}
		},
	}
}

</script>
<style lang="less" scoped>
.flex {
	display: flex;
	justify-content: space-evenly;
}
.tree-row{
	min-width: 200px;
}
.custom-tree-node{
	display: flex;
	flex:1;
	justify-content: space-around;
}
</style>
相关推荐
dsyyyyy110115 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen15 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客17 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖17 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty17 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚18 小时前
软件测试期末考试
vue.js
小二·18 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜19 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain50919 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年27520 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax