1. 程式人生 > >談談Vue的遞迴元件

談談Vue的遞迴元件

2月最後一天,而且還四年一遇,然而本月居然一篇部落格沒寫,有點說不過去。所以,今天就來談談Vue的遞迴元件。我們先來看一個例子:

什麼是遞迴元件

上面這個例子,就是用遞迴元件實現的。遞迴元件,顧名思義,就是自己的內部實現又呼叫自己的元件。比如Vue官方給的treeView的例子,父目錄下有子目錄,子目錄下還有子目錄,子子孫孫,無窮盡也。就像俄羅斯套娃。

程式碼結構大概長下面這樣子,需要注意遞迴元件與一般元件不同的地方是,你需要給元件提供一個name選項,防止Vue編譯的時候,將內部呼叫的Example元件認為是未定義元件,當然,你也可以直接將元件註冊未一個全域性元件。

// example元件的實現
<template>
<div>
  ...
   <Example></Example>
  ...
</div>
</template>

<script>

export default {
    name: 'Example' // 重要
}
</script>

遞迴元件的應用場景

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

寫一個遞迴元件

其實,除了前面所說的name選項是必須的之外,還有一點也是在實現遞迴元件要注意的,就是要防止無限遞迴,造成呼叫棧溢位。上面說的子子孫孫,無窮盡也,說說可以,可是瀏覽器受不了啊。這就要根據實際場景來分析遞迴的終止條件。接下來,我們來寫一個遞迴元件。

上面的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>

全部程式碼可到上面的codepen中檢視,大家週末愉快。2020.02.29