vue 递归实现树形组件
<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>