说明
keep-alive
标签可以让组件持续存活,避免路由刷新造成的页面数据丢失。
加入你在A组件
填写表单,切换到B组件
,此时再返回A组件
,正常情况下,组件会刷新,数据会丢失。
如果该页面被keep-alive
缓存,那么路由跳转切换后,数据还在。
我们来看官方示例:
keep-alive
KeepAlive
<template>
<!-- 将(只)缓存组件name为a或者b的组件, 结合动态组件使用 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 组件name为c的组件不缓存(可以保留它的状态或避免重新渲染) -->
<keep-alive exclude="c">
<component :is="view"></component>
</keep-alive>
<!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 动态判断 -->
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
<!-- 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存a组件 -->
<keep-alive include="a,b" exclude="b">
<component :is="view"></component>
</keep-alive>
<!-- 如果缓存的组件超过了max设定的值5,那么将删除第一个被缓存的组件 -->
<keep-alive exclude="c" max="5">
<component></component>
</keep-alive>
</template>
在上面的示例中,我们通过keep-alive
缓存组件,如果组件name
符合keep-alive
缓存规则,该组件即可被被缓存。
使用keep-alive
缓存组件会触发以下生命周期钩子函数:
- onActivated - 在组件被激活时触发。
- onDeactivated - 在组件被停用时触发。
而以下生命周期钩子函数不会被触发:
- setup 开始创建组件,在 beforeCreate 和 created 之前执行,创建的是 data 和 method
- onBeforeMount 组件挂载到节点上之前执行的函数;
- onMounted 组件挂载完成后执行的函数;
- onBeforeUpdate 组件更新之前执行的函数;
- onUpdated 组件更新完成之后执行的函数;
- onBeforeUnmount 组件卸载之前执行的函数;
- onUnmounted 组件卸载完成后执行的函数;
这些生命周期钩子函数不会被触发是因为被keep-alive
缓存的组件实例在被激活和离开缓存时,并不会重新创建或销毁,而是被缓存起来直接展示或隐藏,初次加载组件会照常触发7个生命周期,而离开后返回时则仅仅触发组件的2个生命周期函数。
组件name
我们在vue3
中给组件添加name
有两种方式,组件的name
可以用于keep-alive
做include
缓存
方式一
新增一个script,通过export default将组件name暴露出去。
<script lang="ts">
export default {
name: "myName",
}
</script>
<script setup lang="ts">
import { ref, reactive } from "vue"
import { Plus, CircleClose } from "@element-plus/icons-vue"
import type { FormInstance } from "element-plus"
// 正常js逻辑......
</script>
方式二
通过插件实现
npm install vite-plugin-vue-setup-extend -D
在vite.config.ts
文件中配置
import vuesetupExtend from 'vite-plugin-vue-setup-extend'
export default defineConfig({
plugins: [vue(),vuesetupExtend()], // 在这里引入
// resolve:{}
})
引入完成后,在页面中的script
上可以直接定义name
<script setup lang="ts" name="myName>
import { ref, reactive } from "vue"
import { Plus, CircleClose } from "@element-plus/icons-vue"
import type { FormInstance } from "element-plus"
// 正常js逻辑......
</script>
路由缓存
我们先来看一组代码
<router-view v-slot="{ Component }">
<keep-alive :include="cachedViews">
<component :is="Component"/>
</keep-alive>
</router-view>
上面的写法实质上跟直接使用router-view
的效果是一致的,如下:
<router-view></router-view>
我们通过router-view
设置路由出口来渲染页面,另外它可以通过插槽的形式动态渲染组件,通过插槽组件的形式渲染的目的是为了配合keep-alive
设置页面缓存。
在这里cachedViews
的数据应该是一个数组,来源于router
的可缓存选项,我们在keep-alive
中利用include
来动态判断该组件是否缓存,如果组件name
在缓存数组cachedViews
中,该组件即可缓存。
我们在动态添加路由的时候会根据路由是否可缓存选项来设置缓存name
,例如:
{
path: "/module-view/Amap",
name: "Amap", // 取该路由的name
component: () =>
import("@/views/module-view/Amap/index.vue"),
meta: {
title: "Amap",
isLink: "",
isHide: false,
isKeepAlive: true, // 路由是否缓存
isAffix: false,
isIframe: false,
roles: ["admin"],
icon: "Menu"
}
},
我们在遍历生成路由时根据isKeepAlive
来生成数据,我们可以将该数据存入全局store
中,为读取缓存提供支持。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。