Vue 3.0 動(dòng)態(tài)組件&異步組件

2021-07-16 11:29 更新

該頁面假設(shè)你已經(jīng)閱讀過了組件基礎(chǔ)。如果你還對(duì)組件不太了解,推薦你先閱讀它。

#在動(dòng)態(tài)組件上使用 keep-alive

我們之前曾經(jīng)在一個(gè)多標(biāo)簽的界面中使用 is attribute 來切換不同的組件:

  1. <component :is="currentTabComponent"></component>

當(dāng)在這些組件之間切換的時(shí)候,你有時(shí)會(huì)想保持這些組件的狀態(tài),以避免反復(fù)重渲染導(dǎo)致的性能問題。例如我們來展開說一說這個(gè)多標(biāo)簽界面:

點(diǎn)擊此處實(shí)現(xiàn)

你會(huì)注意到,如果你選擇了一篇文章,切換到 Archive 標(biāo)簽,然后再切換回 Posts,是不會(huì)繼續(xù)展示你之前選擇的文章的。這是因?yàn)槟忝看吻袚Q新標(biāo)簽的時(shí)候,Vue 都創(chuàng)建了一個(gè)新的 currentTabComponent 實(shí)例。

重新創(chuàng)建動(dòng)態(tài)組件的行為通常是非常有用的,但是在這個(gè)案例中,我們更希望那些標(biāo)簽的組件實(shí)例能夠被在它們第一次被創(chuàng)建的時(shí)候緩存下來。為了解決這個(gè)問題,我們可以用一個(gè) <keep-alive> 元素將其動(dòng)態(tài)組件包裹起來。

  1. <!-- 失活的組件將會(huì)被緩存!-->
  2. <keep-alive>
  3. <component :is="currentTabComponent"></component>
  4. </keep-alive>

來看看修改后的結(jié)果:

點(diǎn)擊此處實(shí)現(xiàn)

現(xiàn)在這個(gè) Posts 標(biāo)簽保持了它的狀態(tài) (被選中的文章) 甚至當(dāng)它未被渲染時(shí)也是如此。你可以在這個(gè)示例查閱到完整的代碼。

你可以在 API 參考文檔查閱更多關(guān)于 <keep-alive> 的細(xì)節(jié)。

#異步組件

在大型應(yīng)用中,我們可能需要將應(yīng)用分割成小一些的代碼塊,并且只在需要的時(shí)候才從服務(wù)器加載一個(gè)模塊。為了簡(jiǎn)化,Vue 有一個(gè) defineAsyncComponent 方法:

  1. const app = Vue.createApp({})
  2. const AsyncComp = Vue.defineAsyncComponent(
  3. () =>
  4. new Promise((resolve, reject) => {
  5. resolve({
  6. template: '<div>I am async!</div>'
  7. })
  8. })
  9. )
  10. app.component('async-example', AsyncComp)

如你所見,此方法接受返回 Promise 的工廠函數(shù)。從服務(wù)器檢索組件定義后,應(yīng)調(diào)用 Promise 的 resolve 回調(diào)。你也可以調(diào)用 reject(reason),以指示加載失敗。

你也可以在工廠函數(shù)中返回一個(gè) Promise,所以把 webpack 2 和 ES2015 語法加在一起,我們可以這樣使用動(dòng)態(tài)導(dǎo)入:

  1. import { defineAsyncComponent } from 'vue'
  2. const AsyncComp = defineAsyncComponent(() =>
  3. import('./components/AsyncComponent.vue')
  4. )
  5. app.component('async-component', AsyncComp)

當(dāng)在本地注冊(cè)組件時(shí),你也可以使用 defineAsyncComponent

  1. import { createApp, defineAsyncComponent } from 'vue'
  2. createApp({
  3. // ...
  4. components: {
  5. AsyncComponent: defineAsyncComponent(() =>
  6. import('./components/AsyncComponent.vue')
  7. )
  8. }
  9. })

#與 Suspense 一起使用

異步組件在默認(rèn)情況下是可掛起的。這意味著如果它在父鏈中有一個(gè) <Suspense>,它將被視為該 <Suspense> 的異步依賴。在這種情況下,加載狀態(tài)將由 <Suspense> 控制,組件自身的加載、錯(cuò)誤、延遲和超時(shí)選項(xiàng)將被忽略。

異步組件可以選擇退出 Suspense 控制,并通過在其選項(xiàng)中指定 suspensable:false,讓組件始終控制自己的加載狀態(tài)。

你可以在中查看可用選項(xiàng)的列表 API 參考

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)