Vue實現遞歸組件的思路與示例代碼

前言

在我們開發過程中,為瞭提高開發效率,降低開發難度,我們會直接使用組件庫來實現,同時也衍生出瞭很多優秀的組件庫,如:餓瞭麼、螞蟻、Iview、vant等等。但是有時這些組件庫提供給我們的組件不滿足我們的需求或者定制組件時成本太高,那麼我們就要手動實現瞭。

一、遞歸組件是什麼?

字面理解為層層遞進最後歸並到一起,它的特點就是層級分明。

例如餓瞭麼組件庫的樹組件就是一個遞歸。

二、Vue實現遞歸的核心思路

1、循環出一級類別

2、判斷如果有多級,再調用自身。

三、代碼示例

1.父級

代碼如下(示例):

<template>
  <div>
    <!-- 遞歸組件 -->
    <Recursion :list="list" />  list為獲取數據,傳入子頁面
  </div>
</template>

<script>
import Recursion from "./recursion.vue";

export default {
  name: "index-Recursion",
  components: {
    Recursion,
  },
};
</script>

2.子級

代碼如下(示例):

<template>
  <div>
    <div class="item">
      <div>
          <ul>
            <li v-for="(l, id) of list" :key="id">
              {{ l.name }}
              <ul style="padding-left: 20px" v-if="l.chidren"> // 核心代碼1
                <li>
                    <index-chird :list="l.chidren" /> // 核心代碼2
                </li>
              </ul>
            </li>
          </ul>
        </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "index-chird", // 自身組件
  props: {
    list: Array,
  },
  data() {
    return {
      list: [],
    };
  },

  watch: {
    list(newData) {
      this.list = newData;
    },
  },
  
};
</script>

<style  scoped>
.item {
  margin: 0 auto;
}
</style>

此處使用監聽器監聽數據變化,如果正常發請求傳遞數據不需要監聽,如果報出沒有拿到數據的錯誤可使用監聽器。

3、實現效果

補充:遞歸組件的應用場景

除瞭上述的樹形視圖外,評論也是一個不錯的應用場景,比如網易新聞的評論回復功能。或者一個包含父任務和多級子任務的todolist,總之,遞歸組件適合那些在UI上有父子關系的場景。

寫一個遞歸組件

其實,有一點也是在實現遞歸組件要註意的,就是要防止無限遞歸,造成調用棧溢出。上面說的子子孫孫,無窮盡也,說說可以,可是瀏覽器受不瞭啊。這就要根據實際場景來分析遞歸的終止條件。接下來,我們來寫一個遞歸組件。

上面的demo實現瞭一個模擬dom事件冒泡的操作,當點擊中心圓時,事件逐級傳遞,然後改變div的顏色,直到冒泡到最頂層。這裡根據設置圓的數量進行遞歸,遞歸的終止條件是直到數量減到1:

<template>
...
    <colorful-circle 
         v-if="count > 1" // 控制遞歸條件
         :count="count - 1" // 每向下一層,count減1
         @colorChange="handleColor" 
    ></colorful-circle>
...
</template>

遞歸組件在事件監聽上也是一個有意思的地方,你可以一層一層接力,直到將事件冒泡到最頂層。代碼片段如下:

<template>
...
    <colorful-circle 
         v-if="count > 1" 
         :count="count - 1"
         @colorChange="handleColor" // 監聽子colorful-circle組件發出的事件
    ></colorful-circle>
...
</template>
 
<script>
name: 'colorful-circle',
...
methods: {
...
    handleColor(c) {
      this.color = Color(c).darkenByAmount( .05 ); // 在本層組件改變顏色
      setTimeout(() => {
        this.$emit('colorChange', this.color); // 把事件再冒泡到上一層組件
      },100)
    },
}
...
</script>

總結

很簡單的一個demo,重點是我們是否瞭解Vue每個組件定義的name的真正用途是什麼。每個組件的name值其實也是為瞭幫助我們實現遞歸的。

代碼邏輯也很簡單,重點在我的子組件。但父組件傳過來的樹形數據結構到子組件後,我們需要拿到數據並做遍歷,然後再下一行加入核心邏輯:if 發現我們有子數據,那麼我們直接調用自身組件,也就是直接使用name值做組件聲明。最關鍵的是要把子數據結構再傳入我們自身組件,那麼我們就成功的實現瞭數據的層層遍歷。

當然,這塊兒的子數據結構字段我這裡叫chirden,一般企業開發是後臺給我們的,他們也可以叫A,叫B,我們需要根據自己的數據字段情況,去做相應的修改。

到此這篇關於Vue實現遞歸組件的文章就介紹到這瞭,更多相關Vue實現遞歸組件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: