场景需求:
从首页的点击导航进入列表页,
列表页点击列表进入 该 数据详情页
从详情页返回,希望列表页缓存,不重新渲染数据。
一、正常增加页面缓存
1、按需缓存组件
在路由信息中再加一个字段,这里是deepth字段,代表进入路由的层级,比如首页路由deepth是0.5,列表页是1,详情页是2
new Router({
routes: [
{
path: '/',
name: 'index',
component: () => import('./views/keep-alive/index.vue'),
meta: {
deepth: 0.5 // 定义路由的层级
}
},
{
path: '/list',
name: 'list',
component: () => import('./views/keep-alive/list.vue'),
meta: {
deepth: 1
keepAlive: true //需要被缓存
}
},
{
path: '/detail',
name: 'detail',
component: () => import('./views/keep-alive/detail.vue'),
meta: {
deepth: 2
}
}
]
})
2、增加监听器
然后在 app.vue中增加监听器,监听 我们进入路由的 方向
<template>
<keep-alive :include="include">
<!-- 需要缓存的视图组件 -->
<router-view v-if="$route.meta.keepAlive">
</router-view>
</keep-alive>
<!-- 不需要缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
</template>
<script>
export default {
name: "app",
data: () => ({
include: []
}),
watch: {
$route(to, from) {
//如果 要 to(进入) 的页面是需要 keepAlive 缓存的,把 name push 进 include数组
if (to.meta.keepAlive) {
!this.include.includes(to.name) && this.include.push(to.name);
}
//如果 要 form(离开) 的页面是 keepAlive缓存的,
//再根据 deepth 来判断是前进还是后退
//如果是后退
if (from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {
var index = this.include.indexOf(from.name);
index !== -1 && this.include.splice(index, 1);
}
}
}
};
</script>
借鉴博主:进入博主链接
二、页面已增加缓存,但需要刷新页面
1、给需要缓存的页面增加时间戳key
new Router({
routes: [
{
path: '/',
name: 'index',
component: () => import('./views/keep-alive/index.vue'),
meta: {
deepth: 0.5 // 定义路由的层级
}
},
{
path: '/list',
name: 'list',
component: () => import('./views/keep-alive/list.vue'),
meta: {
deepth: 1,
keepAlive: true, //需要被缓存
keys:Date.now(),//增加时间戳 key值
}
},
{
path: '/detail',
name: 'detail',
component: () => import('./views/keep-alive/detail.vue'),
meta: {
deepth: 2
}
}
]
})
2、组件渲染 key值处理
<template>
<!-- <RouterView /> -->
<router-view v-slot="{ Component, route }">
<keep-alive :include="include">
<component
:is="Component"
v-if="route.meta.keepAlive"
:key="route.meta.keys ? route.meta.keys : route.fullPath"
/>
</keep-alive>
<component
:is="Component"
v-if="!route.meta.keepAlive"
:key="route.fullPath"
/>
</router-view>
</template>
3、页面中路由跳转增加路由信息的key值处理,达到刷新页面效果
vue3代码为例
/**在 Vue Router 中,使用 router.beforeEach 方法添加的全局守卫是累加的,
* 而不是替换的。因此,如果你在调用 removeGuard 时再次调用
* router.beforeEach ,它不会覆盖之前的守卫,而是会将新的守卫添加到守卫链中。
**/
// 控制守卫是否激活
const isGuardActive = ref(false)
// 添加全局守卫
router.beforeEach(guard)
function guard(to, from, next) {
if (isGuardActive.value) {
to.meta.keys = Date.now()
}
next()
}
// 在某个条件下移除全局守卫
function removeGuard() {
console.log('在某个条件下移除全局守卫')
isGuardActive.value = false // 设置为 false,表示不再执行守卫逻辑
}
//点击跳转按钮
function onSubmit() {
isGuardActive.value = true
router.push({
path: '/carEmpower'
}).then(() => {
/**在 Vue Router 中,使用 router.beforeEach 方法添加的全局守卫是累加的,
* 函数在 onSubmit() 方法中被调用,这会立即将 isGuardActive.value 设置为 false 。
* 因此,当路由切换到 /carEmpower 时, guard 函数会检查 isGuardActive.value 的值,
* 这时它已经是 false 了。
**/
// 在路由切换完成后再调用 removeGuard
removeGuard();
});
}