我想选中tree的节点,并将选中的tree结构完整的复制到右边,展示出来,就像下面这样的:
选中根节点比较好实现,根节点下面的节点都被选中了,从el-tree获取到的node节点中,包含了children的信息;但是子节点甚至是叶子节点选中之后,要将其所有父节点都显示出来,该怎么实现呢?
下面是一种解决办法,没有涉及到parentId。
1、准备好数据
左侧树的数据结构要加上节点所在的层级,如果前端获取的数据没有,那么就要后端准备好数据。
// 这里的数据用type来表示所在层级
const treeData = [
{
id: "539360484919346437",
name: "需求调研",
type: "1",
children: [
{
id: "539737572478289541",
name: "实地走访调查",
type: "2",
children: [
{
id: "540141173788903493",
name: "座谈会",
type: "3",
children: null,
},
],
},
{
id: "540129545349498949",
name: "撰写调研报告",
type: "2",
children: [],
},
{
id: "541961391574093445",
name: "需求问询",
type: "2",
children: [
{
id: "541967629196201669",
name: "办事员需求问询",
type: "3",
children: null,
},
{
id: "541967697315892933",
name: "领导需求问询",
type: "3",
children: null,
},
],
},
],
},
{
id: "539733491076564549",
name: "需求分析",
type: "1",
children: [
{
id: "541967770380668613",
name: "初步需求分析",
type: "2",
children: [],
},
{
id: "541967945023098565",
name: "阶段需求分析",
type: "2",
children: [],
},
],
},
];
2、在获取选中的node时,需要传递参数
el-tree为我们提供了getCheckedNodes
方法来获取被选中的节点,方法有两个参数,含义如下:
这里将第二个参数设置为true,这样点击子节点、叶子节点时,它的所有父节点都会被返回。
getCheckedNodes(false, true)
3、采用递归删除未选中节点的方式,生成一个新的树形结构
我当前的项目是vue项目,treeData是响应式的数据,如果我想生成一个新的树形结构的话,简单的复制treeData是不行的,必须采用深度拷贝的方式,拷贝一份treeData的数据,这方面就不展开了。
递归删除的思路,首先筛选出treeData第一层被选中的数据,如果没有,就删除;然后将层级递增,依次删除。
// el-tree的选择事件
handleCheckChange(e) {
// 获取左侧树,被选中的节点
this.leftCheckedNodes = this.$refs.tree.getCheckedNodes(false, true);
// 使用深度拷贝,拷贝一份treeData的数据
let arr = this.deepClone(this.treeData);
// 使用递归,获取到选中节点的树形结构
this.rightTaskList = this.handleChooseNode(arr, 0);
}
// 深度递归删除,type是当前遍历的层级。
handleChooseNode(arr, type) {
// 因为后端的type是从1开始的,所以这里先+1
type++;
// 获取到选中节点中,属于当前遍历层级的节点
let nodes = this.leftCheckedNodes.filter(o => o.type == type);
// 获取到选中节点中,属于当前遍历层级的节点的所有id
let ids = nodes.map(item => item.id);
// 遍历当前数组
for (let i = 0; i < arr.length; i++) {
// 如果遍历到的节点不在选中的数组中,则删除。
if (!ids.includes(arr[i].id)) {
arr.splice(i--, 1);
} else {
// 否则,如果当前节点的children属性不为空,则递归遍历当前节点的children
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
this.handleChooseNode(arr[i].children, type)
}
}
}
return arr;
}