zoukankan      html  css  js  c++  java
  • vue keep-alive保存路由状态2 (高级用法,接上篇)

    接上篇 https://www.cnblogs.com/wangmaoling/p/9803960.html

    本文很长,请耐心看完分析。

    4.高级用法,指定从什么组件进入才缓存,以及销毁缓存:先介绍我发现的网上一些博主写的有bug的方法,在介绍自己的方法。 

    假设这里有 3 个路由: A、B、C。要求:

      1.   默认显示 A    

      2.  B 跳到 A,A 不刷新 

      3.  C 跳到 A,A 刷新

    先上一些发现博客上有些博主写的实现方式:

    方式1:有bug

      在 A 路由里面设置 meta 属性:

    {
        path: '/',
        name: 'A',
        component: A,
        meta: {
            keepAlive: true // 需要被缓存
        }
    }

      在 B 组件里面设置 beforeRouteLeave:

    export default {
        data() {
            return {};
        },
        methods: {},
        beforeRouteLeave(to, from, next) {
             // 设置下一个路由的 meta
            to.meta.keepAlive = true;  // 让 A 缓存,即不刷新
            next();
        }
    };

      在 C 组件里面设置 beforeRouteLeave:

    export default {
        data() {
            return {};
        },
        methods: {},
        beforeRouteLeave(to, from, next) {
            // 设置下一个路由的 meta
            to.meta.keepAlive = false; // 让 A 不缓存,即刷新
            next();
        }
    };

      这样便能实现 B 回到 A,A 不刷新;而 C 回到 A 则刷新。但是问题来了:

        1. 只要是从C到了A(A即为false),A在到B的时候也是false,B返回A后A才变为true。

          这个方法没弄明白,true跟缓存的关系,只有首先设置了true才可以被缓存,而不是后设置true让他缓存下。

        2. 如果是多页面就麻烦了,每个组件都得写,并且还不知道,to的组件是什么。

    方式2:有bug - $destroy()销毁后就永远不会被缓存了 

    //在router的js里面 加上全局
    Vue.mixin({ beforeRouteLeave: function (to, from, next) {   // 省略若干代码this.$destroy(); next(); } } })

    方式3:有bug。比较暴力的方法,已经很好的方法,根据源码看来缓存的组件都会设置一个cache属性,可以通过代码强行移除掉。缺点就是没有彻底销毁依旧占内存。

      

      

      路由设置:

      

      公共组件设置:

      

      实现:

    Vue.mixin({
      beforeRouteLeave: function (to, from, next) {
        // 默认是缓存的 在来清除
        // 1.用tag标记控制 判断上下级
        // if (from && from.meta.tag && to.meta.tag && (from.meta.tag-to.meta.tag<1))
        // 2.直接用组件名字来写 不够通用
        // if (from.path == '/docMng' && to.path == '/docMng/docDetail') {
        // 3. 用包含关系来判断 通用
          if(to.path.indexOf(from.path)!=-1){
          }else{
        // if (from && from.meta.tag && to.meta.tag && (from.meta.tag-to.meta.tag<1)){
            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()
      }
    })

       此方法可以用了下面说下问题:

      从A组件的详情(A1)直接跳到另一个组件(B),然后在从B到A会发现A没有刷新,按道理是需要刷新的。

    方式4:比较好的解决方法,用到了keep-alive的 include属性。通过vuex动态控制include达到可缓存状态。

      思路:一般设置缓存就是 从A1->A2 这个过程A1需要设置缓存,A1->B1一般是不需要的(tab切换暂不考虑,以后可能会在分析设计)。

        通过vuex要缓存的组件存起来加载到include,来动态控制include。下面上项目截下来的图:

      步骤一路由设置:我这里是用层级表示的路由。这里如果不用层级可以用标记来表示例如:tag1.0 tag1.1 tag1.2     tag2.... 用这个方法来表示的时候需要多处理一   下,这里不做分析了

      

      步骤二vuex设置

      

      步骤三组件内设置在公共main设置观察属性include属性。

      

      步骤四在路由里面进行拦截

      

      

      

  • 相关阅读:
    主席树学习笔记(静态区间第k大)
    p1156 题解(未完全解决)
    树上神奇 逆 逆序对(我的叫法)hh的小纸条 重中之重!!!!!
    二叉查找树学习笔记(BST)
    负环...坑点
    差分约束系统学习笔记
    tarjan学习(复习)笔记(持续更新)(各类找环模板)
    分层图食用简介
    js数组方法
    灵动标签调用父栏目下的所有文章
  • 原文地址:https://www.cnblogs.com/wangmaoling/p/9826063.html
Copyright © 2011-2022 走看看