1、设置缓存对应的数据
-
需要在全局状态管理中,或者当前组件中添加数据(本次演示在全局状态管理中,使用的是 pinia)
const coreStore = defineStore('coreStore', {state () {return {// 缓存页面路由数组及组件cacheRoutes: [],includeComs: [],cacheComs: new Map()}},actions: {setCacheRoute (route: { fullPath: string, name: string }): void {this.cacheRoutes.push(route)}}, })
-
在根组件 App.vue 中引入进来
const store = costore(); const { cacheRoutes, includeComs, cacheComs } = store
2、路由生命周期设置
在 App.vue 组件中,需要设置路由进入前的守卫函数,用于将对应组件进行缓存:
import { useRoute, useRouter } from "vue-router";const route = useRoute();
const router = useRouter();router.beforeEach((to, from, next) => {// 1 判断内部是否已有改缓存页面const bol = cacheRoutes.some(v => v.fullPath === to.fullPath)// 2 如果不存在,则存进缓存标签数组中!bol && cacheRoutes.push({ fullPath: to.fullPath, name: to.meta.title })// 3 缓存组件对应的路由名称!includeComs.includes(to.fullPath) && includeComs.push(to.fullPath);next()
})
3、将路由组件进行缓存
这个是 Vue3 的写法,不适用与 Vue2
<router-view v-slot="{ Component }"><keep-alive :include="includeComs" style="margin-left: 16px;"><component :is="formatComponentInstance(Component, $route)" :key="$route.fullPath" /></keep-alive>
</router-view>
4、formatComponentInstance
这是最重要的一个函数,因为缓存组件的时候 keep-alive 会根据组件名称进行缓存,假设现在有个 A.vue
组件(名称为 A,如果不使用选项式写法,Vue3默认将组件名称作为组件的 name)
在访问 A?a=1
和 A?a=2
两个路径的时候,会导致访问的都是已缓存的组件,不会重新进行挂载渲染
因此需要该函数保证不同路径下,即使组件相同,也能进行重新挂载和缓存
import { compile, h, nextTick, onMounted, ref, watch } from "vue";// 显示组件时,替换组件 name,解决同个组件路由不一致问题
const formatComponentInstance = (component, route) => {let wrapper;if (component) {const wrapperName = route.fullPathif (cacheComs.has(wrapperName)) {wrapper = cacheComs.get(wrapperName);} else {wrapper = {name: wrapperName,render() {return h(component);},}cacheComs.set(wrapperName, wrapper);}}return h(wrapper);
}