关于vue keeplive的刷新缓存终极解决方案,就看下面了,全栈网其他关于解决keeplive的大家就当作参考吧。
另外,我们做路由的时候要有意的根据页面等级做出路由的长度 比如 /a是一级的页面/a/b是二级的页面,下面的文章大家也可以通过判断path的长度来计算rank值,不用有意自定了
这样做的好处有两点,一个就是前进刷新,后退不刷新,还有就是,如果我们做页面进出效果的时候也能排上用场。
遇到这一个个问题 需要是这样的 Vue里面的不刷新问题
页面分为: A 主页 B列表页 C 详情页
A beforeRouteLeave 时设置 to.meta.keepAlive = false (A 进入 B页面时), 不缓存 B列表页
B beforeRouteLeave 时 (B -> C)列表页进详情页时 from.meta.keepAlive =true 缓存B列表页
C详情页 返回 B列表页 ,此时B列表页缓存不生效,也就是第一次不生效
总结问题原因:
当进入B列表页后,keepAlive 为 true 时,缓存生效
当离开B列表页时 设置 keepAlive 为 true 时 ,缓存不生效
这就是很头疼的问题,查阅相关资料找到
解决
在app.vue 页面
<transition :name="transitionName"> <keep-alive> <!-- v-if="isRouterALive" :include="[ keepData ]" --> <router-view class="child-view" v-if="$route.meta.keepAlive" ></router-view> </keep-alive> </transition> <transition :name="transitionName"> <router-view class="child-view" v-if="!$route.meta.keepAlive"></router-view> </transition>
路由页面配置:
{ path: '/activities/create_proto', name: 'create_proto', meta: { index: 2, title: '活动创建', keepAlive: false, //此组件不需要被缓存 rank:1, }, component: () => import (/* webpackChunkName: "create_proto" */'@/pages/activities/create_proto') }, { path: '/activities/create/:id', name: 'create', meta: { index: 2, title: '活动创建', keepAlive: true, //此组件不需要被缓存 isBack:false, //用于判断上一个页面是哪个 rank:1.5, }, component: () => import (/* webpackChunkName: "create" */'@/pages/activities/create') }, { path: '/activities/createMask', name: 'createMask', meta: { index: 2, title: '组', keepAlive: false, //此组件不需要被缓存 isBack:false, //用于判断上一个页面是哪个 rank:1.5, }, component: () => import (/* webpackChunkName: "createMask" */'@/pages/activities/createMask') },
让B页面始终是缓存,
然后在B页面 就是 create页面 里:
beforeRouteEnter(to,from,next){ //来自editNotic的不缓存 if(from.name === 'createMask' && to.name === 'create'){ to.meta.isBack = true; } next(); }, activated() { // console.log(this.$route.meta) if(!this.$route.meta.isBack || this.isFirstEnter){ // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据 this.getApi(); } // 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据 this.$route.meta.isBack=false; //this.isBack = false; this.isFirstEnter = false; }, beforeCreate() { this.$loading.open(); }, mounted(){ this.isFirstEnter = true; this.getApi(); },
解释一波
缓存的页面 created 会执行只有一次,activated每次都会执行 ,
created 里面做 第一次 isFirstEnter = true(由于页面被缓存,所以一直生效),之后再activated 里面做判断
只有 “不是返回回来的” 和 “第一次进来的” 就刷新数据, 并且要在下面 都设为false, 以免缓存各标识不对,
在进入 “列表页” 时,通过router钩子函数 beforeRouteEnter做判断,
详情页过来的设 isBack 为true,即不刷新页面
但第一次都是不生效的,查阅了github 上的大佬方法,就是强制清除B缓存,当B页面离开去到A页面,用rank 来比较
在main.js 中 写入:
Vue.mixin({ beforeRouteLeave: function (to, from, next) { console.log(to) if (from && from.meta.rank && to.meta.rank && from.meta.rank > to.meta.rank) { //如果返回上一层,则摧毁本层缓存。 if (this.$vnode && this.$vnode.data.keepAlive) { if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache) { if (this.$vnode.componentOptions) { 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; if (cache[key]) { if (keys.length) { var index = keys.indexOf(key); if (index > -1) { keys.splice(index, 1); } } delete cache[key]; } } } } this.$destroy(); } next(); }, })
就是强制清除缓存,哇,这个问题搞了半天,
然后就解决了前进刷新,后退不刷的问题,
当然还可以结合vuex 来做到效果,但数据比较大的话还是适合 我写的这种吧,哈哈哈