iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
自我挑戰組

每天來點 Vue.js 吧系列 第 29

Vue 動態組件

tags: Vuejs

動態組件 ✐

動態組件可以幫助我們動態切換組件,例如在網頁的多標籤介面中常見到動態切換組件的需求,便是動態組件能幫忙的場景之一。

使用動態組件

動態組件需要配合 <component> 內置組件以及 :is 這個特殊屬性,下方實作一個簡單的範例:

首先建立要切換的子組件 my-component-onemy-component-two

Vue.component('my-component-one', {
  data() {
    return {
      data: ''
    }
  },
  template: `<p>my-component-one</p>`
})

Vue.component('my-component-two', {
  data() {
    return {
      data: ''
    }
  },
  template: `<p>my-component-two</p>`
})

在父組件中,透過 <component> 組件配合 :is,便可以動態的切換組件。

const vm = new Vue({
  el: '#app',
  data: {
    currentComponent: 'my-component-one'
  },
  template: `<div id="app">
                  <button @click="changeComponent('my-component-one')">my-component-one</button>
                  <button @click="changeComponent('my-component-two')">my-component-two</button>
                  <div>
                      <component :is="currentComponent"/>
                  </div>
            </div>`,
  methods: {
    changeComponent(value) {
      this.currentComponent = value
    }
  },
})

可以觀察到透過動態組件,子組件實體在切換時會被銷毀,並且重新渲染當下的動態子組件。

這裡要記住的重點為:

透過動態組件,子組件 在切換時 instance 會被銷毀以及重新渲染。

透過在子組件生命週期鉤子加入 console 可以看見銷毀以及重新渲染的過程。請在子組件中加入下列代碼:

created() {
    console.log('my-component-two 被渲染了')
},
  destroyed() {
    console.log('my-component-one 被銷毀了')
},

可以看到在切換時子組件被銷毀,當下的動態子組件被渲染、銷毀的過程:

不過,動態組件在切換後由於子組件實體被銷毀,所以子組件本身的狀態也會被清除,這個時候可以透過 <keep-alive> 內置組件保存該子組件 instance。

接著來看看 <keep-alive> 吧!

在動態組件上使用 <keep-alive>

使用 <keep-alive> 這一個內置組件去包裹動態組件,可以緩存不活動的動態組件組件實體,這個時候組件的狀態便可以在切換的過程中保留。

今天假如子組件為下方 input 內容,在沒有使用 <keep-alive> 時使用,狀態無法保留:

我們可以看到切換後 input 內文字消失了。這個時候便可以使用 <keep-alive> 解決該問題。

在使用 <keep-alive> 後,子組件狀態會由於 <keep-alive> 緩存了組件實體而被保留下來。

deactivatedactivated 生命週期鉤子

前面說到使用 <keep-alive> 後,實體將被保留,所以切換動態組件時,並不會觸發子組件的 創建刪除,取而代之的在動態組件使用 <keep-alive> 後,切換組件時有了兩個特有的生命週期鉤子 deactivatedactivated 分別在切換動態組件時調用:

  • deactivated:在 <keep-alive> 緩存的組件被停用(自該組件切換到別的組件)時調用
  • activated:在 <keep-alive> 緩存的組件被激活(切換到該組件)時調用

透過在子組件加上下列程式碼可以觀察上述生命週期:

created() {
    console.log('my-component-one 被創建了')
},
destroyed() {
    console.log('my-component-one 被銷毀了')
},
deactivated() {
    console.log('my-component-two 被停用了')
},
activated() {
    console.log('my-component-two 被激活了')
},

可以觀察到切換動態組件時組件並不會被創建、刪除,而是被激活或是停用。

結語

以上介紹了有關動態組件的使用以及如何保存動代組件的狀態,重點是如何去透過 <keep-alive> 保留組件狀態,並且可以在使用 <keep-alive> 時使用特有的生命週期鉤子。

以上為此次內容,感謝看到這裡的你,我們明天見。


若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦

▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification

▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM


參考資料:

  1. Vuejs.org 2.x

上一篇
Vue slot:作用域插槽、具名插槽的縮寫
下一篇
每天來點 Vue.js 吧 目錄&總結
系列文
每天來點 Vue.js 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Chris
iT邦新手 4 級 ‧ 2020-10-15 00:43:41

鬼牌!

鬼牌這個比喻是?XD

Chris iT邦新手 4 級 ‧ 2020-10-16 17:18:03 檢舉

鬼牌 = 使用時,可以假裝成任何一張牌。
<component> 渲染時,可以假裝成當下指向的任何一個 component

我要留言

立即登入留言