当前位置: 首页 > news >正文

vue中的一个内置组件Keep-Alive的作用及使用方法介绍——缓存不活动的组件实例

一、什么是 keep-alive

在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,也不会进行重新初始化组件。

Keep-Alive是Vue.js中的一个内置组件,它可以用来缓存不活动的组件实例,而不是销毁它们。当Keep-Alive包裹动态组件时,它会将组件的状态保存在内存中,以防止在组件切换过程中重复渲染DOM,从而提高性能和用户体验。Keep-Alive自身不会渲染一个DOM元素,也不会出现在父组件链中。

在Keep-Alive组件中,你可以使用props来控制哪些组件需要被缓存,以及可以缓存多少个组件实例。例如,你可以使用include和exclude props来指定需要缓存的组件名称或正则表达式,以及使用max props来限制最多可以缓存的组件实例数量。

当组件在Keep-Alive内被切换时,它的activated和deactivated生命周期钩子函数将会被对应执行。这意味着当组件从缓存中激活时,activated函数会被调用,而当组件被停用时,deactivated函数会被调用。

优点:
  • 减少页面加载时间,提高页面渲染速度。
  • 缓存已经渲染过的组件,减少内存的占用。
  • 提高用户体验,快速回退之前的组件状态。
  • 节约 HTTP 请求次数,减少服务器压力,提高渲染效率。
缺点:
  • 不利于SEO优化。因为Keep-Alive不会渲染DOM元素,搜索引擎可能无法正确地索引和识别被缓存的组件内容。
  • 可能会增加内存消耗。如果大量组件被缓存,可能会占用大量的内存资源。

因此,在使用Keep-Alive时需要注意权衡其优缺点,根据实际需求和情况做出决策。

二、使用方法:
基本用法:
<!--被keepalive包含的组件会被缓存-->
<keep-alive><component><component />
</keep-alive>
参数:

keepalive 可以接收3个属性做为参数进行匹配对应的组件进行缓存:

  • include 包含的组件(可以为字符串,数组,以及正则表达式,只有匹配的组件会被缓存)
  • exclude 排除的组件(以为字符串,数组,以及正则表达式,任何匹配的组件都不会被缓存)
  • max 缓存组件的最大值(类型为字符或者数字,可以控制缓存组件的个数)

它会根据组件的 name 选项进行匹配,所以组件如果想要条件性地被 KeepAlive 缓存,就必须显式声明一个 name 选项。

其他用法:
<!-- 将(只)缓存组件name为a或者b的组件, 结合动态组件使用 -->
<keep-alive include="a,b"><component></component>
</keep-alive><!-- 组件name为c的组件不缓存(可以保留它的状态或避免重新渲染) -->
<keep-alive exclude="c"> <component></component>
</keep-alive><!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/"><component :is="view"></component>
</keep-alive><!-- 动态判断 -->
<keep-alive :include="includedComponents"><router-view></router-view>
</keep-alive><!-- 如果同时使用include,exclude,那么exclude优先于include, 下面的例子只缓存a组件 -->
<keep-alive include="a,b" exclude="b"> <component></component>
</keep-alive><!-- 如果缓存的组件超过了max设定的值5,那么将删除第一个缓存的组件 -->
<keep-alive exclude="c" max="5"> <component></component>
</keep-alive>
三、生命周期:

被keepalive包含的组件不会被再次初始化,也就意味着不会重走生命周期函数
但是有时候是希望我们缓存的组件可以能够再次进行渲染,这时 Vue 为我们解决了这个问题
被包含在 keep-alive 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated:

  • activated 在首次挂载,以及每次从缓存中被重新插入的时候调用
  • deactivated 在从 DOM 上移除、进入缓存,以及组件卸载时调用
注意:

activated 在组件挂载时也会调用,并且 deactivated 在组件卸载时也会调用。
这两个钩子不仅适用于 缓存的根组件,也适用于缓存树中的后代组件。

生命周期:

页面第一次进入,钩子的触发顺序created-> mounted-> activated,

退出时触发 deactivated
当再次进入(前进或者后退)时,只触发 activated事件挂载的方法等,

只执行一次的放在 mounted 中;
组件每次进去执行的方法放在 activated 中;

export default {mounted(){//只执行一次},activated() {// 每次进去都执行},deactivated() {// 组件卸载时调用}
}
四、缓存页面:

遇见 vue-router 结合router使用,缓存部分页面

所有路径下的视图组件都会被缓存
<keep-alive><router-view><!-- 所有路径匹配到的视图组件都会被缓存! --></router-view>
</keep-alive>
如果只想要router-view里面的某个组件被缓存,怎么办?

1、用 include (exclude例子类似)
缺点:需要知道组件的 name,项目复杂的时候不是很好的选择

<keep-alive include="a"><router-view><!-- 只有路径匹配到的 include 为 a 组件会被缓存 --></router-view>
</keep-alive>

2、使用 meta 属性
优点:不需要例举出需要被缓存组件名称
使用$route.meta的keepAlive属性:

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

需要在router中设置router的元信息meta:

//...router.js
export default new Router({routes: [{path: '/Hello,',name: 'Hello',component: Hello,meta: {keepAlive: false // 不需要缓存}},{path: '/page1',name: 'Page1',component: Page1,meta: {keepAlive: true // 需要被缓存}}]
})

需要注意的是,include和exclude属性中的组件名字必须是组件定义的name属性值,而不是路由里面定义的名字。

五、拓展使用:

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

需求:

默认显示 A
B 跳到 A,A 不刷新
C 跳到 A,A 刷新

实现方式:

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

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

2、在 B 组件里面设置 beforeRouteLeave:

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

3、在 C 组件里面设置 beforeRouteLeave:

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

这样便能实现 B 回到 A,A 不刷新;而 C 回到 A 则刷新。

六、防坑指南:
  • keep-alive 先匹配被包含组件的 name 字段,如果 name 不可用,则匹配当前组件 components 配置中的注册名称。
  • keep-alive 不会在函数式组件中正常工作,因为它们没有缓存实例。
  • 当匹配条件同时在 include 与 exclude 存在时,以 exclude 优先级最高(当前vue 2.4.2 version)。比如:包含于排除同时匹配到了组件A,那组件A不会被缓存。
  • 包含在 keep-alive 中,但符合 exclude ,不会调用 activated 和 deactivated。

相关文章:

  • Redis内存使用率高,内存不足问题排查和解决
  • ctfshow——文件上传
  • nginx+rsyslog+kafka+clickhouse+grafana 实现nginx 网关监控
  • LabVIEW在电机噪声与振动探测的应用
  • dctcp 和 l4s tcp prague
  • 爬虫实战-微博评论爬取
  • ubuntu系统用户登录问题
  • 【逗老师的无线电】ICOM IC-705终端模式Terminal Mode直连反射器配置-内置网关IP直连篇
  • [数理统计]中国科技技术大学缪柏其
  • typescript,eslint,prettier的引入
  • element el-table实现可进行横向拖拽滚动
  • Python异常处理TypeError: translation() got an unexpected keyword argument ‘codeset‘
  • 前端八股文(CSS篇)二
  • Android 13 - Media框架(29)- MediaCodec(四)
  • DNS测试和管理工具
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 30秒的PHP代码片段(1)数组 - Array
  • android 一些 utils
  • C++入门教程(10):for 语句
  • classpath对获取配置文件的影响
  • FastReport在线报表设计器工作原理
  • fetch 从初识到应用
  • Javascript基础之Array数组API
  • JavaScript类型识别
  • mysql innodb 索引使用指南
  • mysql中InnoDB引擎中页的概念
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • SpringCloud集成分布式事务LCN (一)
  • Spring核心 Bean的高级装配
  • Spring声明式事务管理之一:五大属性分析
  • vue-cli3搭建项目
  • 面试总结JavaScript篇
  • 判断客户端类型,Android,iOS,PC
  • 前嗅ForeSpider中数据浏览界面介绍
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 使用SAX解析XML
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • UI设计初学者应该如何入门?
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • (6)添加vue-cookie
  • (Java)【深基9.例1】选举学生会
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (推荐)叮当——中文语音对话机器人
  • (转)Sublime Text3配置Lua运行环境
  • (转)项目管理杂谈-我所期望的新人
  • . NET自动找可写目录
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .Net core 6.0 升8.0
  • .net refrector
  • .net wcf memory gates checking failed
  • .NET 指南:抽象化实现的基类
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析