vue 实现前进不刷新后退刷新

引言:

最近的vue单页面项目要实现一个利用页面缓存的优化, 即前进刷新页面,后退不刷新页面的功能, 并且并列的页面也要实现缓存的效果.

举例: A页面, B页面, C页面

keep-alive:

想要是页面缓存就要用到keep-alive这个标签, 

把keep-aline包裹router-view就能事项页面缓存:

<keep-alive>
        <router-view class="Router" ></router-view>        
</keep-alive>

  但是,并不是所有的页面都要缓存, 有些需要,有些又不需要缓存, 这时候就要用到找个东西来区分他,

meta:路由原信息,

我们利用这个来区分哪些是要缓存,哪些是不要缓存的

在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, 

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

 

  

猜你喜欢

转载自www.cnblogs.com/lianxisheng/p/12110177.html