动态组件 & 异步组件
2022年4月23日大约 2 分钟
动态组件 & 异步组件
在动态组件上使用 keep-alive
我们之前曾经在一个多标签的界面中使用 is attribute 来切换不同的组件:
<component :is="currentTabComponent"></component>
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复渲染导致的性能问题。
重新创建动态组件的行为通常是非常有用的,但是在这个案例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive>
元素将其动态组件包裹起来。
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component :is="currentTabComponent"></component>
</keep-alive>
异步组件
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了实现这个效果,Vue 有一个 defineAsyncComponent
方法:
const { createApp, defineAsyncComponent } = Vue
const app = createApp({})
const AsyncComp = defineAsyncComponent(
() =>
new Promise((resolve, reject) => {
resolve({
template: '<div>I am async!</div>'
})
})
)
app.component('async-example', AsyncComp)
如你所见,此方法接受一个返回 Promise 的工厂函数。从服务器检索组件定义后,应调用 Promise 的 resolve 回调。你也可以调用 reject(reason),来表示加载失败。
你也可以在工厂函数中返回一个 Promise,把 webpack 2 及以上版本和 ES2015 语法相结合后,我们就可以这样使用动态地导入:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
app.component('async-component', AsyncComp)
当在局部注册组件时,你也可以使用 defineAsyncComponent:
import { createApp, defineAsyncComponent } from 'vue'
createApp({
// ...
components: {
AsyncComponent: defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
}
})
与 Suspense 一起使用
异步组件在默认情况下是可挂起的。这意味着如果它在父链中有一个 <Suspense>
,它将被视为该 <Suspense>
的异步依赖。在这种情况下,加载状态将由 <Suspense>
控制,组件自身的加载、错误、延迟和超时选项都将被忽略。
通过在其选项中指定 suspensible: false,异步组件可以退出 Suspense 控制,并始终控制自己的加载状态。