场景1 : 首页index、任务列表页workList、人员列表页pList、人员详情页detail(有写操作)
场景2 : 首页index、任务列表页workList、创建任务页create(创建成功跳回任务列表页)
需求 : 首页进入任务列表页必刷新,任务列表页向前跳转时需要缓存,人员详情页无写入操作、创建任务页不确认创建任务,返回任务列表页不变,否则刷新任务列表页面,并且在ios上页面存在使用keep-alive后返回存在scrollTop不正确的问题
我之前的做法是(有点问题的写法):
beforeRouteLeave(to, from, next) {
if (to.path == "路由") {
to.meta.keepAlive = true;
}else{
to.meta.keepAlive = false;
}
next();
}
bug: 测试发现在有多个不同身份登录人切换时,简单使用改变from.meta.keepAlive值会存在一个问题:使用A角色登陆后,会缓存A的workList数据,再切换用户使用其他角色登陆时,第一次进入workList页面数据是正常的,但是进入一下pList或者create之类的页面再返回时还是会显示A的workList数据。
修复: 修复这个bug时采用了清空keep-alive缓存数据的方法,至于是否进行了写入操作刷新数据则可以通过session来实现,写入操作后添加一个session,返回到keep-alive页面时在activated(){}这个生命周期中来判断session。
activated: 缓存的组件再次进入时会触发
deactivated: 缓存的组件离开时会触发
keep-alive页面中生命周期执行顺序
第一次进入keep-alive组件时,其生命周期执行顺序:
beforeRouteEnter --> created --> mounted --> activated --> deactivated
非首次进入时,其生命周期执行顺序:
beforeRouteEnter -->activated --> deactivated
最终代码如下:
`App.vue`
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
`路由中(router/index)`
const routes = [
{
path: '/workList',
meta:{ title:'任务列表', keepAlive:true, savedPosition:true },
component: () => import('../views/task/workList'),
},
...
]
const router = new VueRouter({
mode: "history",
base: '/',
scrollBehavior(to, from, savedPosition) {//使用savedPosition调整scrollTop不正确的问题
if (savedPosition) {
return savedPosition;
} else {
if (from.meta.saveSrollTop) {
from.meta.savedPosition = document.documentElement.scrollTop || document.body.scrollTop;
}
return {
x: 0,
y: to.meta.savedPosition || 0
};
}
},
routes
})
export default router
`workList`
activated() {//进入页面时,如果是存在状态needRefresh,则置空数据(不会出现明显的刷新)并请求下拉刷新方法,
if(sessionStorage.getItem('needRefresh')){
sessionStorage.removeItem('needRefresh');
this.dataList = [];
this.onRefresh()
}
},
beforeRouteLeave(to, from, next) {
//本项目只有本页面用到了缓存,判断如果是跳转回首页则清空keep-alive;否则就需要对应的移除keys和cache
if (to.path == '/index') {
// 如果项目是有多个页面缓存存在
// var key =
// this.$vnode.key == null
// ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : "")
// : this.$vnode.key;
// var cache = this.$vnode.parent.componentInstance.cache;
// var keys = this.$vnode.parent.componentInstance.keys;
// var index = keys.indexOf(key);
// if (cache[key]) {
// if (keys.length) {
// var index = keys.indexOf(key);
// if (index > -1) {
// keys.splice(index, 1);
// }
// }
// delete cache[key];
// }
//项目中只有这一个页面使用了keep-alive
this.$vnode.parent.componentInstance.cache = {};
this.$vnode.parent.componentInstance.keys = [];
}
next();
}
`在taskDetail/create中,如果进行了写操作或者创建任务成功,则在接口成功后添加一个标示`
ajax(){
if(success){
sessionStorage.setItem("needRefresh",true);
}
}