zoukankan      html  css  js  c++  java
  • 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= 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;
            },
    

    记录滚动的位置:

    beforeRouteLeave(to, from, next) {          
                this.scrollTop = document.querySelector("#scrollRef").scrollTop //记录位置
                if (to.name != 'detail') {
                    this.$destroy()
                }
                next();
            },
            activated() {
                if (!this.$route.meta.isBack || this.isFirstEnter) {
                    this.inits();
                }
                if (this.scrollTop) {
                    document.querySelector("#scrollRef").scrollTop = this.scrollTop //设置位置
                }
                this.$route.meta.isBack = false
                this.isFirstEnter = false;
            },
    

      

     这样就实现前进不刷新后退刷新的功能, 但是我这样做需要每个页面都去写一遍这些步骤,这样感觉不是特别好, 希望能有大神能有更好的办法,

    参考文章:https://www.cnblogs.com/wonyun/p/8763314.html

    补充:

    这种方法,是为了实现同级路由切换也做到缓存效果例如大多数的App, 如果我们同级不不需要做到缓存,那么可以使用一个更加简单的东西:

    使用vue-navigation这个插件:
     

      

  • 相关阅读:
    [hdu5400 Arithmetic Sequence]预处理,容斥
    [hdu5399 Too Simple]YY
    [hdu5396 Expression]区间DP
    [hdu5392 Infoplane in Tina Town]置换的最小循环长度,最小公倍数取模,输入挂
    [bzoj2038 [2009国家集训队]小Z的袜子(hose)] 莫队算法
    [hdu1506 Largest Rectangle in a Histogram]笛卡尔树
    hdu5381 The sum of gcd]莫队算法
    [hdu5389 Zero Escape]数根的性质,DP
    [hdu5387 Clock]时钟夹角问题
    [CodeForces 300D Painting Square]DP
  • 原文地址:https://www.cnblogs.com/lianxisheng/p/12110177.html
Copyright © 2011-2022 走看看