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

2021-07-16 11:29 更新

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

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

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

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

當(dāng)在這些組件之間切換的時(shí)候,你有時(shí)會(huì)想保持這些組件的狀態(tài),以避免反復(fù)重渲染導(dǎo)致的性能問(wèn)題。例如我們來(lái)展開說(shuō)一說(shuō)這個(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í)候緩存下來(lái)。為了解決這個(gè)問(wèn)題,我們可以用一個(gè) <keep-alive> 元素將其動(dòng)態(tài)組件包裹起來(lái)。

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

來(lái)看看修改后的結(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 方法:

const app = Vue.createApp({})


const AsyncComp = Vue.defineAsyncComponent(
  () =>
    new Promise((resolve, reject) => {
      resolve({
        template: '<div>I am async!</div>'
      })
    })
)


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 語(yǔ)法加在一起,我們可以這樣使用動(dòng)態(tài)導(dǎo)入:

import { defineAsyncComponent } from 'vue'


const AsyncComp = defineAsyncComponent(() =>
  import('./components/AsyncComponent.vue')
)


app.component('async-component', AsyncComp)

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

import { createApp, defineAsyncComponent } from 'vue'


createApp({
  // ...
  components: {
    AsyncComponent: defineAsyncComponent(() =>
      import('./components/AsyncComponent.vue')
    )
  }
})

#與 Suspense 一起使用

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

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

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

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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)