一.概念

也就是说,kee-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存 keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,也不会进行重新初始化组件。在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。

三.Props

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例
两个新的生命周期钩子
作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。只适用于keep-alive

四. 生命周期

当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

activated
路由组件被激活时触发。(当进入缓存的路由组件时触发)
使用 keep-alive 会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在 activated 阶段获取数据,承担原来 created 钩子函数中获取数据的任务
你应该初始读取一次数据,比如在created里面, 而activated第一次创建页面时不会激活,缓存之后,第二次进入才会开始激活
// 当缓存组件被激活的时候执行

 activated(){this.userName = this.$route.query.id},

deactivated
路由组件失活时触发。(当离开缓存的路由组件时触发)

五.用法(两种方式)

1.根据条件缓存页面

// 所有路径匹配到的视图组件都会被缓存!
<keep-alive><router-view></router-view>
</keep-alive>// 只缓存组件name为aa或者bb的组件
<keep-alive include="aa,bb"> <component />
</keep-alive>// 组件name为cc的组件不缓存
<keep-alive exclude="cc"> <component />
</keep-alive>// 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存aa组件
<keep-alive include="aa,bb" exclude="bb"> <component />
</keep-alive>// 如果缓存的组件超过了max设定的值3,那么将删除第一个缓存的组件
<keep-alive exclude="c" max="3"> <component />
</keep-alive>

缺点:需要知道组件的 name,项目复杂的时候不是很好的选择

3.结合路由缓存部分页面

优点:不需要例举出需要被缓存组件名称

//在 router 目录下的 index.js 文件里
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import Layout from '@/layout'
export default new Router = [{path: '/admin',component: Layout,redirect: '/admin/user',alwaysShow: true, name: 'Admin',meta: {title: '系统管理',icon: 'documentation'},children: [{path: 'user',component: () => import('@/views/admin/user'),name: 'User',meta: {title: '用户管理',keepAlive: true // 需要缓存}},{path: 'user2',component: () => import('@/views/admin/user2'),name: 'User2',meta: {title: '用户管理2',keepAlive: false // 不需要缓存,默认不缓存,可以不写}}]}
]

App.vue

<template><div id="app"><!-- <router-view/> --><!-- 可以被缓存的视图组件 --><keep-alive><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><!-- 不可以被缓存的视图组件 --><router-view v-if="!$route.meta.keepAlive"></router-view></div>
</template><style>
</style>

使用 router.meta 拓展

当然,也可以通过动态设置route.meta的keepAlive属性来实现其他需求,
首页是A页面
B页面跳转到A,A页面需要缓存
C页面跳转到A,A页面不需要被缓存
思路是在每个路由的beforeRouteLeave(to, from, next)钩子中设置to.meta.keepAlive:

A的路由

{path: '/',name: 'A',component: A,meta: {keepAlive: true // 需要被缓存}
}
export default {data() {return {};},methods: {},beforeRouteLeave(to, from, next) {// 设置下一个路由的 metato.meta.keepAlive = true;  // B 跳转到 A 时,让 A 缓存,即不刷新next();}
};
export default {data() {return {};},methods: {},beforeRouteLeave(to, from, next) {// 设置下一个路由的 metato.meta.keepAlive = false; // C 跳转到 A 时让 A 不缓存,即刷新next();}
};

六/实现前进刷新,返回不刷新

所说的前进刷新后退不刷新是指组件是否重新渲染,比如列表list页面,点击其中的每一项进入详情detail页面,然后从detail页面后退到列表list页面时,list页面没有重新渲染,也没有重新发送ajax请求

routes: [{path: '/',name: 'home',component: Home,meta: {keepAlive: false //此组件不需要被缓存}},{path: '/list',name: 'list',component: List,meta: {keepAlive: true //此组件需要被缓存}},{path: '/detail',name: 'detail',component: Detail,meta: {keepAlive: false // 此组件需要被缓存}}
]

第一次进入keep-alive组件时,其生命周期执行顺序

beforeRouteEnter --> created --> mounted --> activated --> deactivated

非首次进入时,其生命周期执行顺序:

beforeRouteEnter -->activated --> deactivated

,非首次进入keep-alive组件时,正常的vue组件生命周期函数是不会在执行,而会执行keep-alive新增的两个周期钩子函数。同时也可以看出离开keep-alive组件时其destroy周期函数并没有执行,从侧面证明缓存组件并没有销毁。根据介绍,我们可以:

通过利用keep-alive提供activated钩子函数来决定是否进行ajax请求来更新组件,以及deactivated钩子函数来重置页面相关状态。

首先,在每个路由元信息meta中添加一个isBack字段

    ...{path: '/list',name: 'list',component: List,meta: {keepAlive: true, //此组件需要被缓存isBack: false}}...

(list.vue页面 )然后,借助beforeRouteEnter钩子函数来判断页面来源

    beforeRouteEnter(to, from, next) {if(from.name === 'detail') { //判断是从哪个路由过来的,若是detail页面不需要刷新获取新数据,直接用之前缓存的数据即可to.meta.isBack = true;}next();},

最后,需要借助keep-alive提供钩子函数activated来完成是否更新:

  activated() {if(!this.$route.meta.isBack) {// 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据this.getData(); // ajax获取数据方法}// 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据this.$route.meta.isBack = false},

特殊情况,在keep-alive组件前进的页面刷新导致keep-alive组件状态丢失
继续以上面的list、detail页面为例,在进入详情页面后,然后刷新,这时列表页面的缓存的数据都丢失了,由于上面的判断规则也会导致不会重新获取数据。所以对于这种问题,还需要额外加一些判断条件。由于keep-alive第一次进入时会执行created方法,所以利用这点加一个标识来加以判断:

   //第一次进入keep-alive路由组件时created() {this.isFirstEnter = true;// 只有第一次进入或者刷新页面后才会执行此钩子函数,使用keep-alive后(2+次)进入不会再执行此钩子函数},
  activated() {if(!this.$route.meta.isBack || this.isFirstEnter){// 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据// 如果isFirstEnter是true,表明是第一次进入此页面或用户刷新了页面,需获取新数据this.data = ''// 把数据清空,可以稍微避免让用户看到之前缓存的数据this.getData();}// 恢复成默认的false,避免isBack一直是true,导致下次无法获取数据this.$route.meta.isBack=false// 恢复成默认的false,避免isBack一直是true,导致每次都获取新数据this.isFirstEnter=false;},

列表页回到上次浏览位置

条件:1、列表页不可使用懒加载延迟加载数据,2、列表页需要使用keepAlive缓存

beforeRouteLeave(to,from,next){  //离开页面之前将高度存储到sessionStorage。这里不建议用localStorage,因为session在关闭浏览器时会自动清除,而local则需要手动清除,有点麻烦。
sessionStorage.setItem('scrollH',document.getElementById('demo').scrollTop)next()
},
activated(){   //在activated生命周期内,从sessionStorage中读取高度值并设置到domif(sessionStorage.getItem('scrollH')){document.getElementById('demo').scrollTop=sessionStorage.getItem('scrollH')}
},

可使用ref

this.$refs.demo.scrollTop =50;

其他:

参考:
1路由缓存,
2前进后退刷新问题,
3.一直缓存,判断是否第一次进入,或者是否返回,返回重新请求数据刷新页面,不是的话默认缓存

Vue缓存路由(keep-alive)以及新的生命周期相关推荐

  1. React:新旧生命周期及其对比

    文章目录 概述 生命周期(旧) 挂载时 更新时 父组件render setState forceUpdate 卸载时 生命周期(新) 挂载时 更新时 卸载时 新旧生命周期的对比 概述 不管是vue还是 ...

  2. jsonp react 获取返回值_谈谈对 React 新旧生命周期的理解

    前言 在写这篇文章的时候,React 已经出了 17.0.1 版本了,虽说还来讨论目前 React 新旧生命周期有点晚了,React 两个新生命周期虽然出了很久,但实际开发我却没有用过,因为 Reac ...

  3. [vue] vue在created和mounted这两个生命周期中请求数据有什么区别呢?

    [vue] vue在created和mounted这两个生命周期中请求数据有什么区别呢? 看实际情况,一般在 created(或beforeRouter) 里面就可以,如果涉及到需要页面加载完成之后的 ...

  4. React 入门:对比 Reac t的新旧生命周期

    文章目录 如何理解"旧"与"新" 旧 - 生命周期图谱 新 - 生命周期图谱 过时的钩子函数 新增的生命周期钩子函数 改变生命周期的关键版本 新旧生命周期钩子函 ...

  5. vue项目下props传进去的数据,生命周期勾子函数包括watch不触发的解决办法

    vue项目下props传进去的数据,生命周期勾子函数包括watch不触发的解决办法 @TOC 遇到的问题 在深层props过程中,props的数据传到了目标文件 但却没有触发数据更新及页面更新: wa ...

  6. React之新旧生命周期对比

    <!DOCTYPE html> <html> <head> <meat charset="UTF-8"> <title> ...

  7. Vue.js 系列教程 3:Vue-cli,生命周期钩子

    原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...

  8. vue中自定义指令、组件化、生命周期、节流和防抖、获取DOM、mint-ui简介、过渡和动画

    自定义指令: vue中通过directive方法自定义指令,如:自定义一个v-focus指令: <script>Vue.directive('focus', {//通过directive( ...

  9. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

最新文章

  1. python opencv卡尺测量边缘距离
  2. Building an MFC project for a non-Unicode character set is deprecated
  3. 本地方法(JNI)——数值参数与返回值
  4. SparkCore基础
  5. 使用CloudIDE搭建简单java环境
  6. 敏捷开发生态系统系列之一:序言及需求管理生态(客户价值导向-可工作软件-响应变化)...
  7. 使用云CRM的10个理由
  8. 【Linux】最常用命令:简单易学,但能解决95%以上的问题
  9. ZR提高失恋测2(9.7)
  10. 人工智能ai算法_AI算法比您想象的要脆弱得多
  11. 红外测温之MLX90614教程
  12. Win11如何优化服务?Win11优化服务的方法
  13. python编程a的x次方_python平方-Python,平方
  14. 2022-2028全球与中国钢琴艺术培训市场现状及未来发展趋势
  15. activiti 获取审批人员_Activiti审批汇总流程
  16. 虚拟歌手亮相央视元宵晚会,窥探背后的科技力量
  17. radmi4a Android,红米4A(Redmi 4A 全网通)一键ROOT教程,看教程ROOT
  18. VS2015新建MFC工程默认存储位置,默认位置修改
  19. Linux第二周学习笔记(13)
  20. 直播app开发中这几个功能影响后期运营

热门文章

  1. 关于友情的励志故事------火炉的故事
  2. 利用python画爱心表白
  3. python字母对照表_Python中的字母范围
  4. java网络编程 TCP程序
  5. html交互视频如何制作,H5交互视频如何实现?
  6. PLC闪烁电路的实现
  7. bilibili视频流量数据潜望镜
  8. 使用nvm管理node和npm
  9. 硅谷裁员潮下的华人码农
  10. 我记忆中的“集银社”