keep-alive是什么
首先在开始前,我们要先了解一下keep-alive这个组件的基本用法。 这个组件的功能只有一个那就是缓存组件,可以让其包裹的组件不销毁,起到一个缓存的作用。
接受可选的三个参数
- max 缓存的最大组件数量,支持数字和字符串
- include 需要缓存的数据,支持字符串,数组,正则
- exclude 不需要缓存的数据,支持字符串,数组,正则 具体的详细介绍可以看这里
1.App.vue 常规设置
在App.vue中,使用keep-alive,并根据路由meta的keepAlive属性来判断是否需要缓存组件;keep-alive大家都很熟悉,如果启用,页面会被缓存。
注意:这里一定要设置key,要不然缓存不生效\color{red}{注意:这里一定要设置key,要不然缓存不生效}注意:这里一定要设置key,要不然缓存不生效
<keep-alive>
<compoent
:is="Component"
v-if="$route.meta.keepAlive"
:key="$route.name"
/>
</keep-alive>
<compoent
:is="Component"
v-if="!$route.meta.keepAlive"
:key="$route.name"
/>
</router-view>
2.设置router
meta里面的keepAlive字段用来设置页面是否需要缓存,主要给keep-alive组件使用
path: '/',
name: 'A',
component: () => import('@/views/A/index.vue'),
meta: {
title: '首页',
keepAlive: false // 此组件不需要被缓存
}
},
{
path: '/B',
name: 'B',
component: () => import('@/views/B/index.vue'),
meta: {
title: '列表',
keepAlive: false
}
},
{
path: '/C',
name: 'C',
component: () => import('@/views/C/index.vue'),
meta: {
title: '详情',
keepAlive: false
}
}]
到这里,思路就来了,我们可以结合组件路由钩子,在页面跳转的时候,去改变meta的keepAlive值;在B页面设置路由钩子,判断B页面是进入A还是C,如果是C,那么设置B页面meta.keepAlive=true\color{red}{meta.keepAlive=true}meta.keepAlive=true,如果是A,那么反之。
3.新建useKeep.ts
因为用的是vue3,把这个功能写成一个hooks。
// 这里把targetPages参数设置为数组,因为目标页面可能有多个,比如B -> C, B -> D
export function useKeepPage(targetPages: string[]) {
const router = useRouter()
/**
* @description: 更新路由meta.keepAlive值
* @param {name} string 需要修改的路由名称
* @param {val} boolean 修改的值
* @return {*}
*/
const updateRouterKeepAlive = (name: string, val: boolean) => {
router.options.routes.map((item: any) => {
if (item.name === name) {
item.meta.keepAlive = val
}
})
}
/**
* @description: 设置页面缓存
* @param {toName} string 目标页面name
* @param {formName} string 来源页面name
* @return {*}
*/
const setKeepPage = (toName: string, formName: string) => {
// 判断是否进入目标页面
if (!targetPages.includes(toName)) {
updateRouterKeepAlive(formName, false)
} else {
updateRouterKeepAlive(formName, true
}
}
// 设置路由钩子
onBeforeRouteLeave((to, form) => {
setKeepPage(to.name as string, from.name as string)
})
return {
setKeepPage,
updateRouterKeepAlive
}
}