KeepAlive
定义
<KeepAlive>
是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。
使用方法
通常和动态组件<Component>
结合使用
<keep-alive>
<router-view />
</keep-alive>
包含/排除
<KeepAlive>
默认会缓存内部的所有组件实例,但我们可以通过 include
和 exclude
prop 来定制该行为。它会根据组件的 name
选项进行匹配,所以组件如果想要条件性地被 KeepAlive
缓存,就必须显式声明一个 name
选项。
<!-- 以英文逗号分隔的字符串 -->
<KeepAlive include="a,b">
<component :is="view" />
</KeepAlive>
<!-- 正则表达式 (需使用 `v-bind`) -->
<KeepAlive :include="/a|b/">
<component :is="view" />
</KeepAlive>
<!-- 数组 (需使用 `v-bind`) -->
<KeepAlive :include="['a', 'b']">
<component :is="view" />
</KeepAlive>
最大缓存实例数
我们可以通过传入 max
prop 来限制可被缓存的最大组件实例数。
<KeepAlive :max="10">
<component :is="activeComponent" />
</KeepAlive>
缓存实例的生命周期
激活周期:onActivated()
失活周期:onDeactivated()
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
// 调用时机为首次挂载
// 以及每次从缓存中被重新插入时
})
onDeactivated(() => {
// 在从 DOM 上移除、进入缓存
// 以及组件卸载时调用
})
</script>
注意:
-
onActivated
在组件挂载时也会调用,并且onDeactivated
在组件卸载时也会调用。 -
这两个钩子不仅适用于
<KeepAlive>
缓存的根组件,也适用于缓存树中的后代组件。
Suspense
定义
<Suspense>
是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。类似于 keep-alive
不需要任何的引入,可以直接进行使用。自带两个 slot
分别为 default、fallback
。当要加载的组件不满足状态时,Suspense
将回退到 fallback
状态一直到加载的组件满足条件,才会进行渲染。
<Suspense>
可以等待的异步依赖有两种:
-
带有异步
setup()
钩子的组件。
组合式 API 中组件的 setup()
钩子可以是异步的:
export default {
async setup() {
const res = await fetch(...)
const posts = await res.json()
return {
posts
}
}
}
如果使用 <script setup>
,那么顶层 await
表达式会自动让该组件成为一个异步依赖:
<script setup>
const res = await fetch(...)
const posts = await res.json()
</script>
<template>
{{ posts }}
</template>
-
异步组件。
<template> <button @click="loadAsyncComponent">点击加载异步组件</button> <Suspense v-if="loadAsync"> <template #default> <AsyncComponent></AsyncComponent> </template> <template #fallback> <div class="loading">数据加载中......</div> </template> </Suspense> </template> <script> import { defineAsyncComponent } from "vue"; export default { name: "App", data() { return { loadAsync: false }; }, components: { HelloWorld, AsyncComponent: defineAsyncComponent(() => { return import("./components/async-component.vue"); }) }, methods: { loadAsyncComponent() { this.loadAsync = true; } } }; </script>
事件
<Suspense>
组件会触发三个事件:pending
、resolve
和 fallback
。pending
事件是在进入挂起状态时触发。resolve
事件是在 default
插槽完成获取新内容时触发。fallback
事件则是在 fallback
插槽的内容显示时触发。
错误处理
<Suspense>
组件自身目前还不提供错误处理,不过你可以使用 errorCaptured
选项或者 onErrorCaptured()
钩子,在使用到 <Suspense>
的父组件中捕获和处理异步错误。
和其他组件结合
<Suspense>
通常会和 <Transition>
、<KeepAlive>
等组件结合。要保证这些组件都能正常工作,嵌套的顺序非常重要。
<RouterView v-slot="{ Component }">
<template v-if="Component">
<Transition mode="out-in">
<KeepAlive>
<Suspense>
<!-- 主要内容 -->
<component :is="Component"></component>
<!-- 加载中状态 -->
<template #fallback>
正在加载...
</template>
</Suspense>
</KeepAlive>
</Transition>
</template>
</RouterView>