实际项目中,除了基本的树结构,有时还需扩展。如下图层级关系的递归调用,红框中的部分为完全递归组件。
父级:
template
<div class="dept-tree-show">
<div class="teer-deep">
<div class="per-teer first-teer clearfix">
<template v-for="(item) in deptlist">
<div class="pt-item ft-item"
:key="item.id"
v-if="item.treeType==activedepttree.code"
:class="{
'disactive': teer2,
'active': (teer2&&teer2.code==item.code)
}"
@click.stop="openChildren(item)">
<div class="top-title">{{item.name.slice(0,2)}}</div>
<div class="total-more" title="人员列表"
@click.stop="showRelatedUsers(item)">
<i :class="item.userloading?'el-icon-loading':'fa fa-users'"></i>
</div>
<div class="total-title">{{item.name}}</div>
<!-- <div class="total-code">{{item.code}}</div> -->
<div class="total-children" @click.stop="openChildren(item)">
{{(item.children&&item.children.length)?item.children.length:0}}
<i :class="(teer2&&teer2.code==item.code)?'el-icon-arrow-up':'el-icon-arrow-down'"></i>
</div>
</div>
</template>
</div>
<secondtree
v-if="teer2"
:openitem="teer2"
@closetopChildren="closetopChildren"
@showRelatedUsers="showRelatedUsers"></secondtree>
</div>
</div>
js:
//....不完整代码
import secondtree from './dept/childrenteer.vue'
//....不完整代码
components:{
secondtree
}
//....不完整代码
子级:
<template>
<div class="wrap-wrap">
<div class="children-teer-wrap" @click.stop v-if="opendata">
<div class="breaker" :id="opendata.id">
<div class="line">
<div class="line-left"></div>
<div class="line-right"></div>
</div>
<div class="baseinfo">
<div class="l-title">{{opendata.name}}</div>
<div class="l-close" @click.stop="closeChildren(opendata)">收起</div>
</div>
</div>
<div class="per-teer children-teer clearfix">
<template v-for="(item) in opendata.children">
<div
class="pt-item ct-item "
:key="item.id"
@click.stop="openChildren(item)"
:class="{
'disactive': treedata,
'active': (treedata&&treedata.code==item.code)
}">
<div class="top-title">{{item.name.slice(0,2)}}</div>
<div class="total-title">{{item.name}}</div>
<div class="total-more" title="人员列表" @click.stop="showRelatedUsers(item)"><i :class="item.userloading?'el-icon-loading':'fa fa-users'"></i></div>
<!-- <div class="total-code">{{item.code}}</div> -->
<div class="total-children"
@click.stop="openChildren(item)">
{{(item.children&&item.children.length)?item.children.length:0}}
<i :class="(treedata&&treedata.code==item.code)?'el-icon-arrow-up':'el-icon-arrow-down'"></i>
</div>
</div>
</template>
</div>
</div>
<childrentree v-if="treedata" :openitem="treedata" @unActiveParent="unActiveParent" @closeChildren="closeChildren" @showRelatedUsers="showRelatedUsers"></childrentree>
</div>
</template>
<script>
export default {
name:"childrentree",
props:{
openitem:{
type: Object,
default: () => {},
}
},
watch:{
openitem(val){
this.opendata=val;
this.treedata=""
}
},
data(){
return{
opendata:this.openitem,
treedata:""
}
},
methods: {
openChildren(data){
if(this.treedata && this.treedata.code && data&& data.code && this.treedata.code==data.code){
this.treedata="";
}else{
if(data&&data.children && data.children.length){
this.treedata=data;
this.$nextTick(()=>{
document.getElementById(data.id).scrollIntoView({behavior: "smooth"})
})
//
}
}
},
unActiveParent(){
this.treedata="";
},
closeChildren(data){
this.opendata="";
this.$emit('unActiveParent');
this.$emit('closetopChildren');
},
showRelatedUsers(data){
this.$emit("showRelatedUsers",data)
}
},
}
</script>
一些重要的废话放到最后:
1:子组件,即需要递归使用的组件,在js中是要声明name(name:"childrentree")。这样子组件在本身就可以直接使用本身。
2:本例从第二层节点才开始使用递归,所以写发有冗余,可按需精简
3:子组件的事件需要按需区分是要发起仅紧挨着的上层事件(this.$emit('unActiveParent');)还是顶层事件(this.$emit('closetopChildren');)。可以通过接受的方法名进行区分
4:展开某一节点后,节点子集的顶部,即大括号顶部的话,可以使用:(根据具体场景自行判断是否需要使用$nextTick)
document.getElementById(data.id).scrollIntoView({behavior: "smooth"})
如有问题请指正,如有更简洁的事项方式请留下链接(✿◡‿◡)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。