vue之keepAlive使用案例详解

在开发中经常有从列表跳到详情页,然后返回详情页的时候需要缓存列表页的状态(比如滚动位置信息),这个时候就需要保存状态,要缓存状态;vue里提供了keep-alive组件用来缓存状态。
可以用以下几种方案解决问题;

一、利用meta标签

1、首先在路由中的meta标签中记录keepAlive的属性为true

path: '/classify',
  name: 'classify',
  component: () => import('@/views/classify/classify.vue'),
  meta: {
    title: '雷石淘券券',
    keepAlive: true
  }
},

2、在创建router实例的时候加上scrollBehavior方法

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return {
        x: 0,
        y: 0
      }
    }
  }
})

3、在需要缓存的router-view组件上包裹keep-alive组件

<keep-alive>
   <router-view v-if='$route.meta.keepAlive'></router-view>
</keep-alive>
<router-view v-if='!$route.meta.keepAlive'></router-view>

4、由于有些情况下需要缓存有些情况下不需要缓存,可以在缓存的组件里的路由钩子函数中做判断

beforeRouteLeave (to, from, next) {
    this.loading = true
    if (to.path === '/goods_detail') {
      from.meta.keepAlive = true
    } else {
      from.meta.keepAlive = false
     // this.$destroy()
    }
    next()
  },

可以支持组件的缓存,但是这种方法有bug,首先第一次打开页面的时候并不缓存,即第一次从列表页跳到详情页,再回来并没有缓存,后面在进入详情页才会被缓存
并且只会缓存第一次进入的状态,不会重新请求数据,如果当页面A选中一个分类跳到B页面,再从B列表页面跳往详情页,此时会缓存这个状态,并且以后再从A页面的其他分类跳到B页面都不会重新被缓存,以至于每次从详情页返回B页面都会跳第一次缓存的状态;当你的项目只有一种状态需要缓存,可以考虑使用这种方法

二 使用include、exclude属性和beforeRouteEnter钩子函数

首先介绍一下include和exclude vue文档https://cn.vuejs.org/v2/api/#keep-alive
是在vue2.0以后新增的属性
include是需要缓存的组件;
exclude是除了某些组件都缓存;
include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

max只在2.5.0新增,最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

activated 与 deactivated。

简单介绍一下在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated 与 deactivated。
文档:在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 树内的所有嵌套组件中触发。
activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。
activated调用时机:
第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用:

beforeMount=> 如果你是从别的路由/组件进来(组件销毁destroyed/或离开缓存deactivated)=>mounted=> activated 进入缓存组件 => 执行 beforeRouteEnter回调

因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子:// beforeCreate created beforeMount mounted 都不会触发。

deactivated:组件被停用(离开路由)时调用
使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
这个钩子可以看作beforeDestroy的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,你可以放在这个钩子里。
如果你离开了路由,会依次触发:

组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由

项目中缓存使用方法:
1、在创建的router对象上加scrollBehavior方法,同上;
2、将需要缓存的组件加在include属性里

<keep-alive :include="['home','classify','search']">
      <router-view></router-view>
</keep-alive>

3、在beforeRouteEnter的next回掉函数里,对返回A页面不需要缓存的的情况初始化,即将本来需要写在created里的东西写在这里;注意一定要将所有的需要初始化的数据要写一遍,不然会有bug;所以不太推荐

beforeRouteEnter (to, from, next) {
    next(vm => {
      // 通过 `vm` 访问组件实例
      if (from.path !== '/goods_detail') { // 一定是从A进到B页面才刷新
        vm.titleText = vm.$route.query.name
        vm.categoryUpper = vm.$route.query.categoryUpper
        vm.goods = []
        vm.page = 1
        vm.catsIndex = 0
        vm.is_search = false
        vm.getCats2()// 是本来写在created里面的各种
      }
    })
  }

三、使用include、exclude属性和beforeRouteLeave钩子函数和vuex (推荐使用)

第三种方法和第二种相似,不同的地方在于,将需要缓存的组件保存到全局变量,可以在路由的钩子函数里灵活的控制哪些组件需要缓存,那些不需要缓存;跟第二种方法相比,不需要每次再重新初始化数据,但是需要在vuex中保存数据;
上代码
1、在创建的router对象上加scrollBehavior方法,同上;
2、将需要缓存的组件加在include属性里

<keep-alive :include="catch_components">
      <router-view></router-view>
</keep-alive>

3、在store里加入需要缓存的的组件的变量名,和相应的方法;

export default new Vuex.Store({
  state: {
    catch_components: []
  },
mutations:{
    GET_CATCHE_COMPONENTS (state, data) {
      state.catch_components = data
    }
}
})

4、在beforeRouteLeave钩子函数里控制需要缓存的组件

beforeRouteLeave (to, from, next) { //要在离开该组件的时候控制需要缓存的组件,否则将出现第一次不缓存的情况
    this.busy = true
    if (to.path === '/goods_detail') { // 去往详情页的时候需要缓存组件,其他情况下不需要缓存
      this.$store.commit('GET_CATCHE_COMPONENTS', ['home'])
    } else {
      this.$store.commit('GET_CATCHE_COMPONENTS', [])
    }
    next()
  },

另外,在我们的项目中遇到路由相同但参数不同的情况组件被复用,不更新的问题,vue官方给出了 响应路由参数变化

watch: {
    '$route' (to, from) {
      document.title = this.$route.query.name
      this.getDefault() //根据参数数据响应
    }

  },

到此这篇关于vue之keepAlive使用案例详解的文章就介绍到这了,更多相关vue之keepAlive使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue缓存的keepalive页面刷新数据的方法

    用到这个的业务场景是这样的: a页面点击新建列表按钮进入到新建的页面b,填写b页面并点击b页面确认添加按钮,把这些数据带到a页面,填充到列表(数组),可以添加多条, 点击这条的时候进入到编辑页面,确认修改之后,回退到a页面,a页面需要更新这条数据 实现这个功能的时候,由于是路由页面之间的跳转,首先想到的方案有几个:1. 用sessionStorage本地存储:2. 用路由参数带过去:3. 用兄弟组件传值 由于是添加完之后如果按回退是需要退出整个页面,如果用路由跳转,会出现回退到编辑页面了,所以这

  • 解决Vue中使用keepAlive不缓存问题

    1.查看app.vue文件,这个是重点,不能忘记加(我就是忘记加了keep-alive) <template> <div> <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"><

  • Vue keepAlive 数据缓存工具实现返回上一个页面浏览的位置

    需求分析 背景: 1.数据列表页,滚动加载数据: 2.多条数据情况下,点击某一条,进入详细页进行编辑(修改,删除)操作: 3.保存返回上一页: 在上面的情况下,想要保持在上次浏览位置,并且保持数据是最新的: 解决办法 1.原始的办法:在点击详情页的时候,记住浏览位置,传递参数或者存到本地缓存,然后在详情页操作完毕后,返回的时候,路由守卫可以判断,是否详情页跳转回来的,然后让页面滚动到上次记录的位置: 思路是这样,实际操作很麻烦: 2.推荐办法:使用vue动态组件keep-alive,搭配路由守卫

  • vue中keepAlive组件的作用和使用方法详解

    前言 在面试的时候,很多面试官再问vue的时候可能就会提一嘴,你知道keep-alive有什么作用吗? keep-alive是vue内置的一个组件,而这个组件的作用就是能够缓存不活动的组件,我们能够知道,一般情况下,组件进行切换的时候,默认会进行销毁,如果有需求,某个组件切换后不进行销毁,而是保存之前的状态,那么就可以利用keep-alive来实现 <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <keep-alive> 包裹

  • vue之keepAlive使用案例详解

    在开发中经常有从列表跳到详情页,然后返回详情页的时候需要缓存列表页的状态(比如滚动位置信息),这个时候就需要保存状态,要缓存状态:vue里提供了keep-alive组件用来缓存状态. 可以用以下几种方案解决问题: 一.利用meta标签 1.首先在路由中的meta标签中记录keepAlive的属性为true path: '/classify', name: 'classify', component: () => import('@/views/classify/classify.vue'), m

  • Vue.js $refs用法案例详解

    尽管有 prop 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件.为此可以使用 ref 为子组件指定一个引用 ID. ref 为子组件指定一个引用 ID,使父组件能通过 ref 直接访问子组件中的数据 通过 this.$refs.outsideComponentRef 能直接定位到 ref="outsideComponentRef" 的上,并返回该实例化对象 一.ref使用在外面的组件上 <div id="app"> <comp

  • vue封装tabs组件案例详解

    本文实例为大家分享了vue封装tabs组件案例的具体代码,供大家参考,具体内容如下 回顾封装tabs组件熟知运用$children,$parent的案例生成整个容器,通过$children拿取子组件 <template>   <div class="ll-tabs">     <div class="ll-tabs__header">       <div         class="ll-tabs__heade

  • Vue使用Swiper的案例详解

    Vue使用Swiper看这一篇就够了 此案例实现需求 完成swiper动态异步数据下的slide渲染 自定义分页器样式 解决loop:true设置时的事件丢失问题 swiper鼠标移入/移出 暂停/开始轮播 单页面渲染多个swiper组件互不影响 1.引入swiper npm i swiper@5.2.0 2.创建轮播图组件CarouselContainer.vue,详细解析在代码注释中 <template> <div class="CarouselContainer"

  • Vue中keep-alive组件作用详解

    keep-alive组件的作用,供大家参考 作用:用于保留组件状态或避免重新渲染(缓存的作用) 比如:当一个目录页面与一个详情页面,用户经常:打开目录页面=>进入详情页面=>返回目录页面=>打开详情页面,这样目录页面就是一个使用频率很高的页面,那么就可以对目录组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回目录时,都能从缓存中快速渲染,而不用重新渲染. 属性 该标签有两个属性include与exclude: include:字符

  • vue keepAlive缓存清除问题案例详解

    vue项目中经常会用到keepalive来做缓存,在应付基本要求上可以说非常方便.但是遇到同一个页面,根据条件不同,分别缓存或者不缓存,就有些麻烦了. 首先先把坑列出来: 1. <keep-alive v-if="xxx"> <router-view /> </keep-alive> <keep-alive v-else> <router-view /> </keep-alive> 网上很多都是这种方法,用了这种方

  • Vue 过渡(动画)transition组件案例详解

    Vue过度(动画),本质走的是CSS3:transtion,animation. 控制器div显示/隐藏,代码如下: <div id="box"> <input type="button" value="按钮" @click="toggle"> <div id="div1" v-show="isShow"></div> </div&g

  • vue.js+boostrap项目实践(案例详解)

    一.为什么要写这篇文章 最近忙里偷闲学了一下vue.js,同时也复习了一下boostrap,发现这两种东西如果同时运用到一起,可以发挥很强大的作用,boostrap优雅的样式和丰富的组件使得页面开发变得更美观和更容易,同时vue.js又是可以绑定model和view(这个相当于MVC中的,M和V之间的关系),使得对数据变换的操作变得更加的简易,简化了很多的逻辑代码. 二.学习这篇文章需要具备的知识 1.需要有vue.js的知识 2.需要有一定的HTML.CSS.JavaScript的基础知识 3

  • Vue之vue.$set()方法源码案例详解

    在使用vue开发项目的过程中,经常会遇到这样的问题:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 这是因为新加入的属性不是响应式的,因此不会触发视图的更新,通常使用静态方法Vue.set()或者实例方法this.$set()解决 ,使用方式: 对象:this.$set(target,key,  value) 数组:this.$set(target,index,  value) 但不管是静态方法Vue.

  • Vue之监听方法案例详解

    vue中的监听方法 watch 注意 名字 你想监听哪个属性,就要和他起一样的名字 1.作用 用来监听vue实例中的数据变化 可以随时修改状态的变化 2.触发条件 当你监听的属性发生变化时,会自动调用对应的监听方法 3.使用场景 用于异步处理,开销比较大的运算 4.示例 watch:{ name(newvalue,oldvalue){ //计算属性可以接受两个参数,第一个参数是新的属性值,第二参数是老的属性值 // this.age // console.log('name属性发生变化了') c

随机推荐