VUE递归组件使用事例

概念:
组件是能够在它们本身的模板中调用自身的。不过它们只能经过 name 选项来作这件事。html

以前在写组件时总有些疑惑,为何export default导出的对象中有个name属性,今天看过递归组件以后,才发现这个name属性的一个比较重要的做用。(固然。name属性的还有其余的用处)。vue

用法:
一、首先咱们要知道,既然是递归组件,那么必定要有一个结束的条件,不然就会使用组件循环引用,最终出现“max stack size exceeded”的错误,也就是栈溢出。那么,咱们可使用v-if="false"做为递归组件的结束条件。当遇到v-if为false时,组件将不会再进行渲染。this

既然要用递归组件,那么对咱们的数据格式确定是须要知足递归的条件的。就像下边这样,这是一个树状的递归数据。spa

 1 [
 2       {
 3         "name": "黄焖鸡米饭111111111",
 4         cList: [
 5           { "name": "二级黄焖鸡" },
 6           {
 7             "name": "one chicken",
 8             cList: [{ "name": '三级黄焖鸡3333', cList: [{ "name": "四级黄焖鸡" }] }]
 9           }
10         ]
11       },
12       { "name": "2222222222" },
13       {
14         "name": "黄焖鸡米饭33333333", cList: [
15           { "name": "二级黄焖鸡" },
16           { "name": "one chicken" }
17         ]
18       },
19     ]

接下来,咱们就用这个树状数据,作一个简单版的树状菜单。树状菜单,也是递归组件最经常使用的方法之一。code

实践案例:

首先,咱们先建立一个tree组件,这个组件做为使用递归组件的父组件,咱们来看下具体写法component

 1 <template>
 2   <div>
 3     <my-trees :list="list"></my-trees>
 4   </div>
 5 </template>
 6 <script>
 7 import myTrees from './treeMenus'
 8 export default {
 9   components: {
10     myTrees
11   },
12   data () {
13     return {
14       list: [
15         {
16           name: '黄焖鸡米饭111111111',
17           cList: [
18             { name: '二级黄焖鸡' },
19             {
20               name: 'one chicken',
21               cList: [
22                 { name: '三级黄焖鸡3333', cList: [{ name: '四级黄焖鸡' }] }
23               ]
24             }
25           ]
26         },
27         { name: '2222222222' },
28         {
29           name: '黄焖鸡米饭33333333',
30           cList: [{ name: '二级黄焖鸡' }, { name: 'one chicken' }]
31         }
32       ]
33     }
34   },
35   methods: {}
36   
37 }
38 </script>

ok,能够看到,<my-trees />就是咱们说的递归组件,当使用它时,只须要把上边咱们定义好的数据经过props的方式传进去便可。xml

接下来,递归组件接收到了父组件传递的数据,就能够进行递归啦,咱们来看下边的实现:htm

 1 <template>
 2   <ul>
 3     <li v-for="(item,index) in list " :key="index">
 4       <p>{{item.name}}</p>
 5       <tree-menus :list="item.cList"></tree-menus>
 6     </li>
 7   </ul>
 8 </template>
 9  <style>
10    ul{
11     padding-left: 20px!important;
12    }
13  </style>
14 <script>
15     export default{
16         name:'treeMenus',
17         props:{
18             list: Array
19         }
20     }
21 </script>

注意本文开头所说,name属性的使用(你能够把它看成从import导入了一个组件并注册,咱们在temlpate可使用<tree-menus></tree-menus>使用子组件自身进行递归了)对象

总结:
经过props从父组件拿到数据,递归组件每次进行递归的时候都会tree-menus组件传递下一级cList数据,(你们能够想象一下整个过程),整个过程结束以后,递归也就完成了,固然,这段代码只是简单的作了下递归组件的使用。对于折叠树状菜单来讲,咱们通常只会去渲染一级的数据,当点击一级菜单时,再去渲染一级菜单下的结构,如此往复。那么v-if就能够实现咱们的这个需求,当v-if设置为false时,递归组件将不会再进行渲染,设置为true时,继续渲染。blog

最后也为你们准备了一个树状折叠菜单的递归组件实现方式,没有样式你们不要介意啦~

 1 <template>
 2  
 3   <ul>
 4     <li v-for="(item,index) in list" :key="index">
 5       <p @click="changeStatus(index)">{{item.name}}</p>
 6       <tree-menus v-if="scopesDefault[index]" :list="item.cList"></tree-menus>
 7     </li>
 8   </ul>
 9  
10 </template>
11  <style>
12 ul {
13   margin-top: 50px;
14   padding-left: 20px !important;
15 }
16 </style>
17 <script>
18 // import treeMenus from './treeMenu2.vue'
19 export default {
20   name: 'treeMenus',
21   props: {
22     list: Array
23   },
24   data() {
25     return {
26       scopesDefault: [],
27       scopes: []
28     }
29   },
30  
31   methods: {
32     changeStatus(index) {
33       console.log(index);
34       if (this.scopesDefault[index] == true) {
35         this.$set(this.scopesDefault, index, false)
36       } else {
37         this.$set(this.scopesDefault, index, this.scopes[index])
38       }
39     },
40     scope() {
41       this.list.forEach((item, index) => {
42         this.scopesDefault[index] = false
43         if ('cList' in item) {
44           this.scopes[index] = true
45           console.log(item, index)
46         } else {
47           this.scopes[index] = false
48         }
49       })
50       console.log(this.scopesDefault)
51     }
52   },
53   created() {
54     this.scope()
55   }
56 }
57 </script>
相关文章
相关标签/搜索