Vue中的遞歸組件


  遞歸函數我們都再熟悉不過了,也就是函數自己調用自己。遞歸組件也是類似的,在組件的template內部使用組件自身。那遞歸組件有什么使用場景呢? 我們都知道樹這個數據結構就是一種遞歸的結構,因此我們可以用遞歸組件去實現一個Tree效果,一般可以用於多層級的菜單。

首先是我們的Tree組件,它包含n個TreeNode(樹的節點),也就是一級的菜單項。(注: treeData數據摘取自ElementUI的樹形組件示例)

<template>
  <div id="app">
    <!-- 一級菜單列表-->
    <ul>
      <TreeNode v-for="nodeData in treeData" :nodeData="nodeData" :key="nodeData.label"></TreeNode>
    </ul>
  </div>
</template>
<script>
  import TreeNode from '../components/TreeNode'
  export default {
    name: 'Tree',
    components: { TreeNode },
    data () {
      return {
        treeData: [
          {
            label: '一級 1',
            children: [{
              label: '二級 1-1',
              children: [{
                label: '三級 1-1-1'
              }]
            }]
          }, {
            label: '一級 2',
            children: [{
              label: '二級 2-1',
              children: [{
                label: '三級 2-1-1'
              }]
            }, {
              label: '二級 2-2',
              children: [{
                label: '三級 2-2-1'
              }]
            }]
          }, {
            label: '一級 3',
            children: [{
              label: '二級 3-1',
              children: [{
                label: '三級 3-1-1'
              }]
            }, {
              label: '二級 3-2',
              children: [{
                label: '三級 3-2-1'
              }]
            }]
          }]
      }
    }
  }
</script>

然后我們來實現TreeNode組件。

<template>
  <li>
    <!-- 菜單項標題和展開/收起按鈕-->
    <div>
      <span>{{nodeData.label}}</span>
      <span v-if="hasChild" @click="open = !open">[{{open ? '-' : '+'}}]</span>
    </div>
    <!-- 子菜單 -->
    <ul v-show="open" v-if="hasChild">
      <TreeNode v-for="childNodeData in nodeData.children" :nodeData="childNodeData" :key="childNodeData.label"></TreeNode>
    </ul>
  </li>
</template>
<script>
  export default {
    // 必須要寫name, 否則在組件內部使用TreeNode標簽將無法解析
    name: 'TreeNode',
    props: ['nodeData'],
    data: function () {
      return {
        // 標識展開/收起狀態
        open: false
      }
    },
    computed: {
      // 是否有子菜單
      hasChild: function () {
        return this.nodeData.children && this.nodeData.children.length
      }
    }
  }
</script>
<style scoped>
  span {
    font-size: 36px;
  }
</style>

  我們都知道,一級菜單下面可能還包含多個二級菜單,二級菜單下面可能包含多個三級菜單,以此類推...因此,在TreeNode組件的template中我們再次使用了TreeNode組件,從而形成了遞歸組件。

運行效果如下,點擊 + / - 號按鈕可以實現展開和收起:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM