vue keepalive 前进刷新后退不刷新终极解决方案

2020-01-17 08:44:57

关于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 来做到效果,但数据比较大的话还是适合 我写的这种吧,哈哈哈


  • 2021-01-13 13:36:29

    shortid nodejs短id生成器

    短ID在实际运用中很广泛, 其中比较典型的运用就是短地址。 市面上肯定有不少开源的生成短ID库, 基于node.js的估计也不少。 鉴于本人已然是node.js的脑残粉(本职java开发), 很多业余项目从前端到后端都基于javascript开发, 加上npm和bower的包管理以及grunt的打包工具, 在项目开发过程中体验特别酸爽。 由于当时项目前后端都会用到短ID, 但没找到合适的库同时支持npm和bower的(可能孤陋寡闻). 因此自己乐此不疲地又造了个轮子js-shortid(夷,为什么会说又呢?!). 下面主要介绍它的实现方案, 自认为比较优雅简洁。

  • 2021-01-13 17:23:21

    CREATE TABLE 表名 AS SELECT 语句 快速复制表但是锁表

    注意Table2的主键约束,如果Table2有主键而且不为空,则 field1, field2…中必须包括主键 在执行语句的时候,MySQL是逐行加锁的(扫描一个锁一个),直至锁住所有符合条件的数据,执行完毕才释放锁。所以当业务在进行的时候,切忌使用这种方法。 在RR隔离级别下,还会加行锁和间隙锁

  • 2021-01-13 17:27:04

    Navicat配置mysql数据库用户权限

    用数据库的时候就会遇到有多个用户,分配用户权限的情况,有些用户只读,有些用户可以读写,有些用户只能操作一个或者多个数据库,如何给mysql的用户设置权限,我这里描述一下如何用navicat图形操作分配用户权限

  • 2021-01-14 06:15:04

    通过glide获取图片显示后的真正宽高

    有时候需要获取网络图片的宽高来设置图片显示的大小,很多人会直接利用Glide的加载监听去拿图片的宽高,但是这样拿到的不是图片真正的宽高,而是图片显示在ImageView后的宽高。如下:

  • 2021-01-14 09:38:57

    Chrome插件详细教程

    严格来讲,我们正在说的东西应该叫Chrome扩展(Chrome Extension),真正意义上的Chrome插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于Chrome插件的叫法已经习惯,本文也全部采用这种叫法,但读者需深知本文所描述的Chrome插件实际上指的是Chrome扩展。

  • 2021-01-14 17:07:51

    chrome.contextMenus.create不出现菜单

    主要原因是,我每次刷新玩,都复制一下右键,然而并没有出现菜单,一度颓废啊,因为demo,还有其他人的文章都是这样的。 哎,后来发现是这样的,我缺少了contexts选项。其实我是成功了,我现在只要不选择文字,直接点右键,菜单已经出现了哦。