最近的vue单页面项目要实现一个利用页面缓存的优化, 即前进刷新页面,后退不刷新页面的功能, 并且并列的页面也要实现缓存的效果.
想要是页面缓存就要用到keep-alive这个标签,
把keep-aline包裹router-view就能事项页面缓存:
<keep-alive>
<router-view class="Router" ></router-view>
</keep-alive>
但是,并不是所有的页面都要缓存, 有些需要,有些又不需要缓存, 这时候就要用到找个东西来区分他,
我们利用这个来区分哪些是要缓存,哪些是不要缓存的
在router.js里面给每个路由都添加
{
path: ‘/home‘,
name: ‘home‘,
component: () =>
import (‘@/views/Home.vue‘),
meta: {
keepAlive: true, //此组件需要被缓存
},
},
{
path: ‘/home‘,
name: ‘home‘,
component: () =>
import (‘@/views/Home.vue‘),
meta: {
keepAlive: false, //此组件不需要被缓存
},
},
在app.vue里面通用meta来区分
<keep-alive>
<router-view class="Router" v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view class="Router" v-if="!$route.meta.keepAlive"></router-view>
做了上面的处理后, 就已经可以实现缓存了, 但是如果一个页面有多个入口进入, 第一个入口进入了,第二个再进入,那么就会造成数据不会刷新的后果,
这时候我们可以给每个路由在添加一个用于刷新: isBack
{
path: ‘/home‘,
name: ‘home‘,
component: () =>
import (‘@/views/Home.vue‘),
meta: {
keepAlive: true, //此组件需要被缓存
isBack: false
},
},
他们执行的顺序是 :beforeRouteEnter ---- > beforeRouteLeave --------> activated,
beforeRouteEnter 和 beforeRouteLeave都是组件内部的导航钩子, 每次离开和进入都会触发,
activated:是只有在keep-alive有的情况下才出现的钩子, 每次进入组件都会触发, (create只有在第一次进入组件才会触发)
比如从B页面进入A页面:
判断是不是B页面来的, 如果是B页面来的就设置isBack=true, activated中就不会执行初始化的代码, 如果不是B页面来就是false(说明是A页面来的),就执行初始化的代码
这样就实现了动态缓存了:
beforeRouteEnter(to, from, next) {
if (from.name == ‘B页面‘) {
to.meta.isBack = true;
}
next();
},
activated() {
if (!this.$route.meta.isBack) {
this.inits();
}
this.$route.meta.isBack = false
this.isFirstEnter = false;
},
如果我现在从B到了C页面, 这时候我刷新了页面, 那么页面上的所有数据都会初始化, 然后我在回到B页面,这时,from.name == ‘C页面‘, to.meta.isBack.isBack = true,
这时候就不会重新加载数据了,但是问我原来的数据也初始化了,这就会出现问题.
解决办法:添加另外一个参数 isFirstEnter = true
created() {
this.isFirstEnter = true;
},
beforeRouteEnter(to, from, next) {
if (from.name == ‘C页面‘) {
to.meta.isBack = true;
}
next();
},
activated() {
if (!this.$route.meta.isBack || this.isFirstEnter) {
this.inits();
}
this.$route.meta.isBack = false
this.isFirstEnter = false;
},
当点击的页面越多的时候,缓存就会越多,缓存 太多之越来越多之后页面就会越来越卡,
使用: beforeRouteLeave 判断将要去的是哪个页面, 如果不是去的下个页面(那肯定是上个页面), 那么就直接销毁掉本页面
beforeRouteEnter(to, from, next) {
if (from.name == ‘detail‘) {
to.meta.isBack = true;
}
next();
},
beforeRouteLeave(to, from, next) {
if (to.name != ‘下个页面‘) {
this.$destroy()
}
next();
},
activated() {
if (!this.$route.meta.isBack || this.isFirstEnter) {
this.inits();
}
this.$route.meta.isBack = false
this.isFirstEnter = false;
},
这样就实现前进不刷新后退刷新的功能, 但是我这样做需要每个页面都去写一遍这些步骤,这样感觉不是特别好, 希望能有大神能有更好的办法,
参考文章:https://www.cnblogs.com/wonyun/p/8763314.html
原文:https://www.cnblogs.com/lianxisheng/p/12110177.html