vue keep-alive的那些坑
前言
写了几个项目,中间使用不同的keep-alive
用法,发现这东西并没有想象中的那样简单,一不小心就会踩坑。
KeepAlive
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
当组件在 <keep-alive>
内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。include
和 exclude
prop
允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。匹配首先检查组件自身的 name
选项,如果 name
选项不可用,则匹配它的局部注册名称 (父组件 components
选项的键值)。匿名组件不能被匹配。
当我们使用<keep-alive>
组件时的期望:
第一次进入页面:beforeCreate
=> created
=> beforeMount
=> mounted
=> activated
跳出页面:deactivated
第二次进入页面:activated
方案一
网上很多keepAlive
方案都是如下这种
// App.vue |
以上代码我们将Home页做了keepAlive,打印Home页的生命周期为:
第一次进入Home页:beforeCreate
=> created
=> beforeMount
=> mounted
=> activated
跳出Home页:deactivated
=> beforeDestroy
=> destroyed
第二次进入Home页:beforeCreate
=> created
=> beforeMount
=> mounted
=> activated
???缓存了个寂寞???
我们将About页面也加上keepAlive
// router |
重复上次操作,打印Home页的生命周期为:
第一次进入Home页:beforeCreate
=> created
=> beforeMount
=> mounted
=> activated
跳出Home页:deactivated
第二次进入Home页:activated
发现结果是我们想要的了,但是这样并不能满足实际使用情况,所以我们先还原
// router |
回顾代码发现其实是v-if
销毁了router-view
组件,所以此种方案PASS
方案二
受上述案例提醒,router-view
只能使用一个,那么只能从keep-alive
找方案了
<!-- App.vue --> |
// 获取所有需要keepAlive的页面name,name需要跟component name相同 |
执行以上代码:
第一次进入Home页:beforeCreate
=> created
=> beforeMount
=> mounted
=> activated
跳出Home页:deactivated
第二次进入Home页:activated
注意
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。
其他问题方案
做APP的时候我们一般都会有这样的场景:
首页
=>列表
=>详情
|详情
=>列表
列表
页面需要缓存列表
=>首页
列表
页面需要主动清除缓存
解决方案一: this.$destroy()
解决方案二: 动态控制include
注意:
方案一有BUG,推荐使用方案二