组件在它的模板内可以递归地调用自己,只有当它有 name
选项时才可以。
首先我们来看下父组件和使用的数据格式:
<template>
<div>
<my-trees :list="list"></my-trees>
</div>
</template>
<script>
import myTrees from './treeMenu2';
export default{
data(){
return {
list:[
{"name":"黄焖鸡米饭111111111",cList:[
{"name":"二级黄焖鸡"},
{"name":"one chicken",cList:[{"name":'三级黄焖鸡3333',cList:[{"name":"四级黄焖鸡"}]}]}
]},
{"name":"2222222222"},
{"name":"黄焖鸡米饭33333333",cList:[
{"name":"二级黄焖鸡"},
{"name":"one chicken"}
]},
]
}
},
methods:{},
components:{
myTrees
}
}
</script>
好,接下来我们就开始来看子组件是如何使用递归的,
按照html的实现思路就是,ul内嵌套li,然后继续在li里边嵌套ui、li,一直循环往复,我们先看下子组件的代码:
<template>
<ul>
<li v-for="(item,index) in list " >
<p>{{item.name}}</p>
<tree-menus :list="item.cList"></tree-menus>
</li>
</ul>
</template>
<style>
ul{
padding-left: 20px!important;
}
</style>
<script>
import treeMenus from './treeMenu2.vue';
export default{
name:'treeMenus',
props:{
list:Array
}
}
</script>
注意本文开头所说,
name属性的使用(类似于从外部import导入了一个组件并注册,我们在temlpate可以使用<tree-menus></tree-menus>使用子组件自身进行递归了)
上边代码通过props从父组件拿到数据,然后进行传递,子组件每次进行递归的时候都会tree-menus组件传递下一级cList数据,(大家可以想象一下整个过程),整个过程结束之后,递归组件也就完成了,当然,这段代码只是简单的做了下递归组件的使用,真正项目中我们不会一次性全部将整个数据全部渲染出来,而是类似于下拉菜单那样的效果。这里就要用到v-if指令了,我直接贴出代码,各位下去可以研究下,代码也非常简单
<template>
<ul>
<li v-for="(item,index) in list " >
<p @click="changeStatus(index)">{{item.name}}</p>
<tree-menus v-if="scopesDefault[index]" :list="item.cList"></tree-menus>
</li>
</ul>
</template>
<style>
ul{
padding-left: 20px!important;
}
</style>
<script>
import treeMenus from './treeMenu2.vue';
export default{
name:'treeMenus',
props:{
list:Array
},
data(){
return {
scopesDefault:[],
scopes:[]
}
},
methods:{
changeStatus(index){
if(this.scopesDefault[index]==true){
this.$set(this.scopesDefault,index,false);
}else{
this.$set(this.scopesDefault,index,this.scopes[index]);
}
},
scope(){
this.list.forEach((item,index)=>{
this.scopesDefault[index]=false;
if('cList' in item){
this.scopes[index]=true;
console.log(item,index);
}else{
this.scopes[index]=false;
}
});
console.log(this.scopesDefault)
}
},
created(){
this.scope();
}
}
</script>