keep-alive 是vue内置的一个组件,其作用是缓存不活动的组件。众所周知,一般在组件进行切换时,默认会进行销毁。若想在组件切换时保存原有的状态,那就需要利用 keep-alive 来实现。
keep-alive 的用法也不复杂,官网也做了说明,并给了示例。但有时规规矩矩的用了就是不生效。相信大家也会有这样的烦恼,接下来小编就列举下容易造成 keep-alive 失效的几个点。
案例
- 关键词没拿捏好,一行注释都能让你忙活一上午。
<keep-alive>
是用在其一个直属的子组件被切换的情形。“一个”、“直属”这两点很好理解,却容易被忽视。有时为了提高代码可读性,我们会做个注释。而这个注释位置要是不对,违反了“一个”原则,就能造成 keep-alive
失效。
1 | <!--掉坑,失效--> |
关于“直属”,或许你能拍胸脯告诉我你不可能因为这点翻车。我承认在刚开始开发项目时,开发者都头脑清晰,加上有官方文档的辅助能很好的规避掉错误点。但随着项目战线拉长,快速的需求变更迭代,难保你在实现功能过程中会不小心掉入了“直属”的坑中。
1 | <!--掉坑,失效--> |
<keep-alive>
直属子组件中使用了v-for
。
1 | <!--失效--> |
- 你给我的,却不是我想要的。
这里就涉及到 keep-alive 的俩 prop(include
和 exclude
)。简单介绍下这俩 prop 的类型:
include
-string | RegExp | Array
。只有名称匹配的组件会被缓存。exclude
-string | RegExp | Array
。任何名称匹配的组件都不会被缓存。
『你给我的,却不是我想要的』大概有这三种情形:
include
(exclude
)设置正确,使用了动态组件但并未在页面中引入相关组件;- 找错对象了,易发在
keep-alive
结合router-view
使用的场景,使用了vue-router
的 name 属性来设置include
(exclude
); include
(exclude
)给的值与组件自身的name
或是局部注册名称不匹配,定义时是小驼峰写法,使用时是大驼峰写法;
这三点中最容易犯错的就是第二点,所以重要的事情要强调下。
vue-router 的 name 属性是用于路由跳转!!!
- 用逗号分隔字符串来表示
include
和exclude
时,因多余空格导致失效。
为防止这种错误发生,推荐使用另外两种方式表示。正则表达式或一个数组。
1 |
|
- 在
Vue3
中局部注册匿名组件后,缓存失效。
include
和exclude
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。
按照官方文档的意思,只有组件自身 name 不可用(我的理解是就未指定 name),才匹配它的局部注册名称。这里我在Vue2 和 Vue3都做了试验,发现两者表现不同。
Vue2写法:
1 | <template> |
Vue3写法,相同部分的代码已省略
1 | <template> |
通过对比我们可以发现除了因 Vue 版本造成的写法不同外,二者并无差异。但运行后表现出在 Vue2 中keep-alive
功能正常,在 Vue3 中却失效。要是你的项目是用 Vue3 开发的,你就老老实实的给组件指定 name 吧。
- 匿名组件造成
keep-alive
失效。
匿名组件就是未指定 name 的组件,但你要是通过局部(全局)组件注册后,它就是具名组件了。项目中容易出现匿名组件的就是Vue页面,keep-alive
结合 router-view
使用就容易让你困在vue-router 的 name 属性中,切记这个 name 属性只用于路由跳转。
vue2写法:
1 | <keep-alive> |
vue3写法:
1 | <router-view v-slot="{ Component }"> |
- 多级路由导致缓存失效
多级路由一般出现在功能繁杂的后台管理系统中,为提高系统性能和改善用户体验,产品可能会要求对页面进行缓存以达到快速地在页面间来回切换。keep-alive 进而在管理系统中崭露头角,但其表现极其不稳定,着实让人摸不着头脑。
Layout.vue
1 | <template> |
NestRouterView.vue
1 | <template> |
router.js
1 | const routes = [ |
这里多级路由缓存失效的原因是借助了『空组件』(NestRouterView.vue)。关于缓存的设置也仅限生效于二级路由中,三级路由中并未涉及到 keep-alive,也就无从谈及失效一说。如何解决多级路由缓存失效问题,请移步小编的另一篇文章vue多级路由缓存(keep-alive)失效的解决方案。
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。
函数式组件只是函数,无状态 (没有响应式数据),也无实例 (在vue2中,没有 this
上下文)。
以上是目前小编所知的8种失效场景。只有规避掉失效点,才能真正用好 keep-alive
。
小结
include
和exclude
推荐使用正则表达式或一个数组来表示;- 需要缓存的组件都写
name
属性,杜绝匿名组件; - 认清
keep-alive
和vue-router
的关系,杜绝乱用name
; - 面对多层
router-view
嵌套,找准keep-alive
位置;
本文作者: mileOfSunshine
本文链接: https://mileofsunshine.github.io/2022/05/11/2022-05-11-how-to-use-keep-alive/
版权声明:文章是原创作品。转载请注明出处!