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属性。

  

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

  

 

  

原文地址:https://www.cnblogs.com/wangmaoling/p/9826063.html

时间: 2024-07-31 03:22:13

vue keep-alive保存路由状态2 (高级用法,接上篇)的相关文章

vue keep-alive保存路由状态1 (接下篇)

本文很长,但是很详细,请耐心看完就一目了然了有下篇 keep-alive 是 Vue 内置的一个组件,使被包含的组件保留状态,或避免重新渲染. 1. 基础用法,缓存所有路由: <keep-alive> <router-view> <!-- 这里是会被缓存所有的视图组件 --> </router-view> </keep-alive> 如果想要单一缓存一个怎么办呢?看下面 2. 初级用法,缓存指定路由: vue 2.1.0后提供了include/e

Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画进行了很大幅度的改进,之前补间动画可以做到的属性动画也能做到,补间动画做不到的现在属性动画也可以做到了.因此,今天我们就来学习一下属性动画的高级用法,看看如何实现一些补间动画

vue路由高级用法

五.路由设置高级用法alias 别名 {path:'/list',component:MyList,alias:'/lists'}redirect 重定向 {path:'/productList',redirect:'/list'}path:'*' 异常处理 {path:'*',component:'NotFound'} <!doctype html> <html> <head> <meta charset="UTF-8"> <ti

使用序列化保存对象状态到存储介质

//使用序列化保存对象状态到存储介质 //添加[Serializable] Game game = new Game(); game.Level = 2; game.Player = "Tom"; FileStream fs = new FileStream(@"game.bin",FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs,game); //使用反序列化

使用SQL Server保存Session状态,实现单点登录

在做一些应用网站时,我们可能会碰到这样一种情况:整个项目是由多个网站组成的,而我们要实现用户从一个站点登录后,跳转到其他网站不需要重复登录,即实现单点登录.目前实现单点登录的技术也有好几种,这篇文章描述一下如何使用ASP.NET2.0和SQL Server来实现单点登录.一般在用户登录成功后,我们需要把用户登录成功的信息保存在Session里,但是Session的值只能保存在用户当前访问的站点下,只要我们实现了Session的跨站共享,也就基本上实现了用户在一个站点登录成功后在其他站点不需要重复

【前端小小白的学习之路】vue学习记录④(路由传参)

通过上篇文章对路由的工作原理有了基本的了解,现在我们一起来学习路由是如何传递参数的,也就是带参数的跳转. 带参数的跳转,一般是两种方式: ①.a标签直接跳转. ②点击按钮,触发函数跳转. 在上篇文章中我们已经有两个页面(Helloworld.vue&Hello.vue),现在我准备往Hello.vue里面添加3个链接,分别对应两种情况的跳转.  第一步:在原来的Hello.vue里添加路由链接跳转的代码(见第38-44行代码),添加后的Hello.vue代码如下: 1 <template&g

保存页面状态

问题: 页面中有菜单页和内容页,都在同一个页面显示.问题是刷新之后,或者从某个页面跳转到另外一个内容页面的时候,菜单状态失效或者页面会到首次登陆状态. 要求: 1. 刷新或者重新加载时,保持页面(菜单页和内容页)状态: 2. 页面内部功能回退:能正常回退: 3. 退出时,清除所有状态. 方案: 1. 分别保存菜单状态和页面状态: 2. 提供修改菜单和页面状态的方法, 提供清除状态的方法: 3. 刷新或者加载时,能够利用缓存中的状态: 4. 退出或者登录时,清除所有状态. 保存页面状态

ps netstat pid 来保存服务状态

要将部分服务器移到其他机柜,重启后不知道哪些服务要启,可以通过以下方法来保存服务状态及路径和执行命令等 1.ps ps f -eo pid,tty,stat,time,command > ${HOSTNAME}_$(date +%Y%m%d)_ps 2.netstat netstat -tupnl > ${HOSTNAME}_$(date +%Y%m%d)_netstat 3.cmdline cat /proc/2644/cmdline /usr/bin/redis-server /etc/r

Fragment-如何监听fragment中的回退事件与怎样保存fragment状态

一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退事件时,想当然的也想着重写onBackPressed()方法,这时候你会发现:Fragment中根本就没有onBackPressed()方法给你重写.这可怎么破! 想想,在前面的例子中,我们在Activity的一个fragment_container里依次Add进fragment1,fragment