vue 递归实现树形组件

时间:2024-12-20 07:13:11
<template> <div class = "loginModuel"> <my-tree :treeMenu='tree' @selectnode="selectnode"></my-tree> </div> </template> <script> export default{ data(){ return{ msg:"这是登录页面", tree:[ { id:1, label:"1级目录1", check:false, children:[ { id:"1-1", pid:1, label:"1.1目录", check:false }, { id:"1-2", pid:1, label:"1.2目录", check:false }, { id:"1-3", pid:1, label:"1.3目录", check:false }, ] }, { id:2, label:"1级目录2", check:false, children:[ { id:"2-1", label:"2.1目录", check:false, pid:2, children:[ { id:"2-1-1", pid:'2-1', label:"2.1.1目录", check:false, children:[ { id:"2-1-1-1", pid:'2-1-1', label:"2.1.1.1目录", check:false, children:[ { id:"2-1-1-1-1", pid:'2-1-1-1', label:"2.1.1.1.1目录", check:false, }, { id:"2-1-1-1-2", pid:'2-1-1-1', label:"2.1.1.1.2目录", check:false, }, ] }, ] }, { id:"2-1-2", pid:'2-1', label:"2.1.2目录", check:false, }, { id:"2-1-3", pid:'2-1', label:"2.1.3目录", check:false, }, ] }, { id:"2-2", pid:2, label:"2.2目录", check:false } ] },//在此继续添加目录 { id:3, label:"1级目录3", check:false, children:[ { id:"3-1", pid:3, label:"3.1目录", check:false, children:[ { id:"3-1-1", pid:"3-1", label:"3.1.1目录", check:false, children:[ { id:"3-1-1-1", pid:"3-1-1", label:"3.1.1.1目录", check:false, children:[ { id:"3-1-1-1-1", pid:"3-1-1-1", label:"3.1.1.1.1目录", check:false }, ] }, ] }, ] } ] }, ], plist:[],//此级以上所有父节点列表 flatTree:[],//tree的平行数据 node:'',//当前点击的node, } }, methods:{ //将tree树形数据转换为平行数据 transformData(tree){ tree.forEach(item=>{ this.flatTree.push(item); item.children && item.children.length>0 ? this.transformData(item.children) : "" }) }, //子组件传递过来的点击的node的值 selectnode(node){ this.node=node; this.flatTree=[]; this.transformData(this.tree); if(node.check==false){//这个节点已经被选中,正在点击取消选中 this.plist=[];//每次点击一个新的节点都将原来plist的内容清空 this.getParentnode(this.flatTree,node.pid) }else{//正在选中 this.childAllToParent(node,this.flatTree,1); } }, //子节点取消选中,拿到此子节点所有的父节点plist getParentnode(tree,pid){ //=[] if(pid!==null){ tree.forEach(item=>{ if(item.id==pid){ this.plist.push(item) this.getParentnode(this.flatTree,item.pid) } }) } if(!pid){ this.plist.forEach(item=>{ this.updateParentCheck(this.tree,item) }) } }, //将原数据tree对应id的项的check值改为false updateParentCheck(tree,plistItem){ //("方法updateParentCheck接收的plistItem参数:",plistItem) tree.forEach(item=>{ if(item.id==plistItem.id){ item.check=false; } if(item.id!==plistItem.id && item.children){ this.updateParentCheck(item.children,plistItem) } }) }, //子节点全部选中后父节点选中 childAllToParent(node,flatTree,j){ let fatherNode=''; let brotherNode=[]; this.flatTree.forEach(item=>{ if(node.pid && node.pid==item.id){ fatherNode=item;//找到了父节点--用于改变check的值 } }) //判断该结点所有的兄弟节点是否全部选中 flatTree.forEach(item=>{ if(item.pid && node.pid && item.pid==node.pid){ brotherNode.push(item)//找到所有的兄弟节点 } }) //i为被选中的兄弟节点的个数 let i=0; this.flatTree.forEach(item=>{ if(node.pid==item.pid && item.check==true){ i=i+1; } }) //修改父节点的选中值 if(i==brotherNode.length && fatherNode){ fatherNode.check=true } // (`第j次递归 j=${j}`) // (`选中的bro=${i},brother的个数:${}`) // ("父节点:",fatherNode,"兄弟节点",brotherNode) if(fatherNode.pid!==undefined){ j=j+1; this.childAllToParent(fatherNode,this.flatTree,j) } } }, mounted(){ this.transformData(this.tree);//数据初始化:将tree树形数据转换为平行数据 //() } } </script>