在项目里经常会遇到以下情况,填单页跳转到选择信息页(eg:选择地址、选择证件),再返回到填单页时,填单页信息不变。可以使用Vue的内置的keep-alive缓存组件来实现以上功能。
1. 使用
在App.vue中加入keep-alive
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
<TabBar />
</div>
</template>
在路由文件中,给需要缓存的页面加上meta
{
path: '/fillorder/:code',
name: 'fillorder',
component: Fillorder,
meta: {
keepAlive: true,
},
},
2. 销毁
以上操作已经可以实现填单页的缓存,但是页面加载一次后变不会再重新请求数据,这并不能满足我们的需求。我们希望填单页返回到上一页再进入填单页时页面会重新加载。
所以,我们首先尝试在组件内的路由守卫,通过页面的去向改变该页面的keepAlive
beforeRouteLeave(to, from, next) {
if (to.name === 'selectAddr') {
from.meta.keepAlive = true;
} else {
from.meta.keepAlive = false;
}
next();
},
然后,再次进入页面可以重新加载。但是由于页面进入时是 keepAlive: false
,所以会导致出现两个<FillOrder>
组件。但问题来了,此时跳转选择地址页面再回到填单页时,显示的填单页是上一次的缓存,这样就导致显示不正确了。
keep-alive并未提供销毁包含组件的方法,但我们可以通过比较hack的方式去实现。
function removeKeepAliveCache () {
if (this.$vnode && this.$vnode.data.keepAlive && this.$vnode.parent) {
const tag = this.$vnode.tag;
let caches = this.$vnode.parent.componentInstance.cache;
let keys = this.$vnode.parent.componentInstance.keys;
for (let [key, cache] of Object.entries(caches)) {
if (cache.tag === tag) {
if (keys.length > 0 && keys.includes(key)) {
keys.splice(keys.indexOf(key), 1);
}
delete caches[key];
}
}
}
this.$destroy();
};
然后,在组件里的路由守卫调用removeKeepAliveCache
,同时也不需要去修改from.meta.keepAlive
了
beforeRouteLeave(to, from, next) {
if (to.name === 'selectAddr') {
// from.meta.keepAlive = true;
} else {
// from.meta.keepAlive = false;
removeKeepAliveCache.call(this);
}
next();
},
至此,就实现了我们开头所说的需求,填单页跳转到选择地址页,再返回到填单页时,填单页信息不变。再次重新进入填单页时,页面会刷新。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。