如何使用vue遞歸組件


  首先我們要知道,既然是遞歸組件,那么一定要有一個結束的條件,否則就會使用組件循環引用,最終出現“max stack size exceeded”的錯誤,也就是棧溢出。那么,我們可以使用v-if="判斷條件"作為遞歸組件的結束條件。當遇到v-if為false時,組件將不會再進行渲染

1. 准備一個樹狀的遞歸數據  這里演示一個側邊欄組件

navigation: [
        {
          types: 1,
          id: "0",
          name: "首頁",
          path: "/jiaowu_system/home",
          icon: "icon_hrIndex.png",
          children: []
        },
        {
          types: 1,
          id: "1",
          name: "教學資源",
          path: "",
          icon: "jiaowu_system_jiaoxueziyuan.png",
          children: [
            {
              types: 2,
              id: "1 - 1",
              name: "學校信息",
              path: "/jiaowu_system/SchoolInformation",
              icon: "",
              children: []
            },
            {
              types: 2,
              id: "1 - 2",
              name: "管理部門信息",
              path: "/jiaowu_system/administration",
              icon: "",
              children: []
            }
          ]
        },
        {
          types: 1,
          id: "2",
          name: "教學計划",
          path: "",
          icon: "jiaowu_system_jihua.png",
          children: []
        }
]

2. 創建一個簡單的遞歸組件 

 // 這里 我是通過name實現遞歸效果的 你可以把它當作從import導入了一個組件並注冊,我們在temlpate可以使用<list-menu></list-menu>使用子組件自身進行遞歸了   默認不展示子組件,只能在父組件點擊的時候才會展示 使用的 v-show  減少渲染消耗

<template>
  <div class="list">
    <div @click.prevent="handleClick">
      {{ model.name }}
    </div>
    <div v-show="reveal" v-if="isDispaly" style="margin-left:20px;">
      <list-menu v-for="item in model.children" :key="item.id" :model="item" />
    </div>
  </div>
</template>

<script>
export default {
  name: "listMenu",
  components: {},
  props: ["model"],
  data() {
    return {
      reveal: false
    };
  },
  methods: {
    handleClick() {
      if (this.isDispaly) {
        this.reveal = !this.reveal;
      }
    }
  },
  computed: {
    isDispaly() {
      return this.model.children && this.model.children.length;
    }
  }
};
</script>

<style scoped>
div {
  width: 100px;
  margin: 20px 0;
}
</style>

上述代碼中我們需要注意,這個組件必須含有 name 這個屬性,因為沒有 name 這個屬性會造成控件自身不能調用自身, 當使用它時,只需要把上邊我們定義好的數據通過props的方式傳進去即可

3. 我們創建一個sidebar組件,這個組件作為使用遞歸組件的父組件 

  // navigation的數據在上面 需要copy 

<template>
  <div class="sidebar">
    <div v-for="menu in navigation" :key="menu.id">
      <list-menu :model="menu"></list-menu>
    </div>
  </div>
</template>

<script>
import listMenu from "./list";
export default {
  name: "sidebar",
  components: {
    listMenu
  },
  props: {},
  data() {
    return {
      navigation: [] // 數據太長 就不在這里面寫了
    };
  }
};
</script>

  好了 我們就實現了一個簡單的遞歸側邊欄組件,這段代碼只是簡單的做了下遞歸組件的使用。對於折疊樹狀菜單來說,我們一般只會去渲染一級的數據,當點擊一級菜單時,再去渲染一級菜單下的結構,如此往復。那么v-if就可以實現我們的這個需求,當v-if設置為false時,遞歸組件將不會再進行渲染,設置為true時,繼續渲染。組件中的name不僅可以遞歸的時候使用 還可以當項目使用keep-alive時,可搭配組件name進行緩存過濾

一個簡單的小實例

<div id="app"> 
    <keep-alive exclude="Detail">
        <router-view/>
    </keep-alive>
</div>


免責聲明!

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



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