vue如何实现路由缓存
(以下示例皆是以vue3+vite+ts项目为例)
场景一:所有路由都可以进行缓存
在渲染路由视图对应的页面进行缓存设置,代码如下:
<template>
<router-view v-slot="{ Component, route }">
<transition name="router-fade" mode="out-in">
<keep-alive>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</transition>
</router-view>
</template>
<router-view>:用来渲染当前路由对应的视图。
v-slot
:解构router-view
的插槽属性来访问当前路由的组件(Component)和路由对象(route)。
<transition>:用于实现页面路由切换时的过渡动画效果,可省略。
name="router-fade"
:定义过渡动画类名为router-fade
,如router-fade-enter-active
。mode="out-in"
:设置过渡模式为先出后进,即新组件先渲染,旧组件再离开
切记:虽然vue3支持一个组件中有多个根节点,但是<transition>不支持多个根节点,否者页面无法正确显示,例如:打开缓存过的页面会出现白屏现象。
<keep-alive>:用来缓存路由组件。
<component>:用来动态渲染组件。
:is="Component"
:表示要渲染的组件由Component
变量决定。:key="route.fullPath"
:为组件添加唯一的键值,确保路由发生变化时触发组件的重新渲染。
场景二:动态设置可以缓存的路由
1. 在router中配置keepAlive,设置支持缓存的页面,例如
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Layout from '../views/layout/index.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Layout',
component: Layout,
meta:{
keepAlive:true //支持缓存
}
},
{
path: '/about',
name: 'About',
component: () => import("../views/about/index.vue"),
meta:{
keepAlive:false //不支持缓存
}
},
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
2. 在支持缓存的对应页面中设置name ,此name必须于路由中设置的name一致。
<script setup lang="ts">
// 使用 defineOptions 设置组件的 name 属性
defineOptions({
name: 'Layout'
});
</script>
3.在渲染路由视图对应的页面进行缓存设置,代码如下:
(相比场景一,多了:include="cachedViews"的设置)
<template>
<router-view v-slot="{ Component, route }">
<transition name="router-fade" mode="out-in">
<keep-alive :include="cachedViews">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</transition>
</router-view>
</template>
<script setup lang="ts">
import {ref,watchEffect} from "vue";
import { useRoute } from 'vue-router';
// 定义缓存的视图数组
const cachedViews=ref<string[]>([])
const route = useRoute();
// 监听路由变化
watchEffect(() => {
const name = route.name as string;
if (route.meta.keepAlive) {
if (!cachedViews.value.includes(name)) cachedViews.value.push(name);
} else {
const index = cachedViews.value.indexOf(name);
if (index > -1)cachedViews.value.splice(index, 1);
}
});
</script>