在开发中经常有从列表跳到详情页,然后返回详情页的时候需要缓存列表页的状态(比如滚动位置信息),这个时候就需要保存状态,要缓存状态;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的使用的更多相关文章

  1. vue中keepalive怎么理解?​---vue中文社区

    vue中keepalive怎么理解? 说在前面: keep-alive是vue源码中实现的一个组件, 感兴趣的可以研究源码 https://github.com/vuejs/vue/blob/dev/ ...

  2. Vue中keep-alive的使用

    Vue中keep-alive的使用我总结的有两种方式应用: 首先简述一下keep-alive的作用,kee-alive可以缓存不活动的的组件.当组件之间进行相互切换的时候,默认会销毁,当重新切换回来时 ...

  3. Vue中keep-alive组件的理解

    对keep-alive组件的理解 当在组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能等问题,使用<keep-alive>包裹动态组件时,会缓存不活动的组件实例, ...

  4. vue中keep-alive的用法

    1.keep-alive的作用以及好处 在做电商有关的项目中,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页,这时候我们使用keep-al ...

  5. vue中 keep-alive 组件的作用

    原文地址 在vue项目中,难免会有列表页面或者搜索结果列表页面,点击某个结果之后,返回回来时,如果不对结果页面进行缓存,那么返回列表页面的时候会回到初始状态,但是我们想要的结果是返回时这个页面还是之前 ...

  6. vue中keepAlive的用法[返回页面不刷新]

    本文转载于時間蒼白了誓言_49b9 使用vue单页开发项目时遇到一个问题:在列表页进入详情页,按返回键返回列表页时页面刷新了,用户体验非常差啊!!!查阅了一下相关问题,使用解决这个问题,下面是我的使用 ...

  7. vue中keep-alive使用时,注意要点

    <keep-alive exclude="QRCode,NewsInfor,VipRecordDetail"> <router-view></rout ...

  8. vue中keep-alive

    vue2.0提供了一个keep-alive组件用来缓存组件,避免多次加载相应的组件,减少性能消耗 1.基本用法,缓存整个页面或组件 <keep-alive> <component&g ...

  9. vue 中 keep-alive 缓存数据、离开时位置

    路由中: 页面中: 需要缓存的组件中: 因为是keep-alive  所以在初始化页面的时候 会走一次生命周期 当二次进入的时候就已经是缓存状态了 不会在走生命周期 于是它就有了自己的周期函数分别是 ...

随机推荐

  1. 转载-通过ApplicationContext 去获取所有的Bean

    Spring Boot - 获取所有的Bean信息 阅读目录 前言 通过ApplicationContext 去获取所有的Bean 前言 Spring Boot启动的时候需要加载许多Bean实现最小化 ...

  2. 常用的app包名和类名

    应用 包名 启动类 QQ com.tencent.mobileqq com.tencent.mobileqq.activity.HomeActivity 微信 com.tencent.mm com.t ...

  3. linux服务器上配置进行kaggle比赛的深度学习tensorflow keras环境详细教程

    本文首发于个人博客https://kezunlin.me/post/6b505d27/,欢迎阅读最新内容! full guide tutorial to install and configure d ...

  4. jQuery 源码分析(十五) 数据操作模块 val详解

    jQuery的属性操作模块总共有4个部分,本篇说一下最后一个部分:val值的操作,也是属性操作里最简单的吧,只有一个API,如下: val(vlaue)        ;获取匹配元素集合中第一个元素的 ...

  5. Spring中ApplicationListener的使用

    背景 ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Appl ...

  6. Serlvet、JSP和JSTL的联系

    没有无缘无故的爱和恨,没有无缘无故的编程 前言: 想这世间,没有无缘无故的爱,也没有无缘无故的恨,一切都有有原因的,我想编程亦是如此,技术时常更新,程序员时常学习,随着时间的推移,程序员发际线的增高, ...

  7. MySQL的基本概念和数据操作

    1.连接服务器 数据库是CS模式的软件,所以要连接数据库必须要有客户端软件.MySQL数据库默认端口号是3306         1.1window界面连接服务器         1.2通过web窗体 ...

  8. golang中type常用用法

    golang中,type是非常重要的关键字,一般常见用法就是定义结构,接口等,但是type还有很多其它的用法,在学习中遇到了以下几种,这点简单总结记录下 定义结构 type Person struct ...

  9. jQuery之概念以及基本使用

    1. jQuery的概述 1.1 jQuery的概念 jQuery是一个快速.简洁的JavaScript库,其设计的宗旨是“Write Less,Do More” jQuery主要是封装了JavaSc ...

  10. [转]C++字符串操作函数_tcschr、_tcsrchr

    原文出处:https://blog.csdn.net/eickandy/article/details/50083169 C++标准库函数提供了字符和字符串的操作函数,并提供了其UNICODE版本,本 ...