keep-alive
这个组件是个特殊的组件,可以让内部的组件被缓存。
Props:
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。max
- 数字。最多可以缓存多少组件实例。
用法:
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
当组件在 <keep-alive>
内被切换,它的 activated
和 deactivated
这两个生命周期钩子函数将会被对应执行。
在 2.2.0 及其更高版本中,
activated
和deactivated
将会在<keep-alive>
树内的所有嵌套组件中触发。
主要用于保留组件状态或避免重新渲染。
1 | <!-- 基本 --> |
注意,<keep-alive>
是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for
则不会工作。如果有上述的多个条件性的子元素,<keep-alive>
要求同时只有一个子元素被渲染。
include
and exclude
2.1.0 新增
include
和 exclude
prop 允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
1 | <!-- 逗号分隔字符串 --> |
匹配首先检查组件自身的 name
选项,如果 name
选项不可用,则匹配它的局部注册名称 (父组件 components
选项的键值)。匿名组件不能被匹配。
max
2.5.0 新增
最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
1 | <keep-alive :max="10"> |
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。
两个新的生命周期
这两个生命周期只有在keep-alive
组件内才生效。
activated
类型:
Function
详细:
被 keep-alive 缓存的组件激活时调用。
该钩子在服务器端渲染期间不被调用。
deactivated
类型:
Function
详细:
被 keep-alive 缓存的组件失活时调用。
该钩子在服务器端渲染期间不被调用。
注意以下几点
- 这两个方法只有在
keep-alive
组件内才会被调用。不在keep-alive
内的组件没有这两个生命周期。activated
在第一次加载时也会调用。deactivated
在页面第一次失效时也会被调用。keep-alive
内的组件第一次加载会先调用mounted
,再调用activated
,之后再加载该页面就只调用activated
。- 服务端渲染这两个生命周期不生效。
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
实际使用
实际开发时我们会这样使用
方式1 自定义属性判断是否缓存
1 | <keep-alive> |
路由中添加
1 | { |
方式2 根据层级摧毁缓存
摧毁相同层级的其他路由
这种方式不适用多标签
组件内添加和mounted
同级
1 | beforeRouteLeave(to, from, next) { |
对应的路由
1 | [{ |
方式3 Vuex中缓存打开标签的路由,删除所有非打开路由缓存。