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>
相關文章
相關標籤/搜索