小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
闲时要有吃紧的心思,忙时要有悠闲的趣味
前言
作为一个vue为主要技术栈的前端,keep-alive是很常用的一个内置组件。下面我们来了解一下其使用和注意事项。
正文
一、keep-alive介绍
keep-alive是什么
keep-alive是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。主要用于保留组件状态或避免重新渲染。
使用场景
用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面。 如果未使用keep-alive组件,则在页面回退时仍然会重新渲染页面,我们希望:
- 列表页点击商品跳转到详情,返回后仍显示原有信息,保留用户的筛选(或选中)状态
keep-alive就是用来解决这种场景的。
当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。 总的来说,keep-alive用于保存组件的渲染状态。
二、keep-alive的用法
keep-alive的三个参数
-
include - string | RegExp | Array:定义缓存白名单,只有名称匹配的组件会被缓存(2.1.0 版本后)。
-
exclude - string | RegExp | Array:定义缓存黑名单,任何名称匹配的组件都不会被缓存, 优先级大于include(2.1.0 版本后)。
-
max - number | string:最定义缓存组件上限,超出上限使用LRU的策略置换缓存数据。
在动态组件中的应用
<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
<component :is="currentComponent"></component>
</keep-alive>
不过此种方式并无太大的实用意义。
在vue-router中的应用
- 在vue2中,可以直接包裹
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
- 在vue3中,旧版的语法已经失效,新版官方推荐使用:
transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
keep-alive的生命周期
- 初次进入时:
-
触发
setup>beforeCreate>created>beforeMount>mounted>activated -
退出后触发
deactivated
- 再次进入:
-
触发
beforeUpdate>updated>activated -
退出后触发
deactivated
一般的组件,每一次加载都会有完整的生命周期,即生命周期里面对应的钩子函数都会被触发。
被keep-alive包裹的组件却不是这样,不再进入$mount过程,mounted之前的所有钩子函数(beforeCreate、created、mounted)都不再执行。它有自己独有的两个生命周期:
- actived 当keep-alive包含的组件再次渲染的时候触发。
- deactived 当keep-alive包含的组件销毁的时候触发
因此,在使用keep-alive时,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中。
三、keep-alive使用的注意事项
include无效
- 检查版本
确定当前的vue版本的是2.1+, 因为include和exclude是vue2.1.0新增的两个属性.
查看 package.json
"vue": "^2.5.2",
- 检查name
注意, 不是 router.js 中的 name , 而是单个 vue 组件中的 name 属性.
建议将 router.js 中的 name 和 vue 组件的 name 保持一致, 不要混乱.
export default {
name: "index"
}
- 多层嵌套
凡有超过两个以上的router-view且是父子级关系, 请都加上keep-alive, 只加一个不会生效.
// app.vue
// other.vue
总结
与诸君共勉,为自己加油!
参考文档
后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址
文档协议
db 的文档库 由 db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。