前言
Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染dom,达到缓存的效果
- include: 字符串或正则表达式。只有匹配的组件会被缓存。
- exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
用法
keep-alive 需要配合 router-view 使用
1 | <template> |
生命周期
activated
deactivated
因为 keep-alive 会将组件保存在内存中,并不会销毁以及重新构建,所以不会重新调用组件的 created等 方法,需要用 activated和deactivated 得知当前组件是否处于活动状态
原理
created 与 destroyed 钩子
created钩子 会创建一个cache对象,用来作为缓存容器,保存vnode节点
1 | created () { |
destroyed钩子 则在组件被销毁的时候清除cache缓存中的所有组件实例
1 | /* destroyed钩子中销毁所有cache中的组件实例 */ |
render
- 通过 getFirstComponentChild 获取第一个子组件,
- 获取该组件的 name (存在组件名则直接使用组件名,否则会使用tag)
- 将这个 name 通过 include 与 exclude 属性进行匹配
- 匹配不成功(说明不需要进行缓存)则不进行任何操作直接返回vnode
1 | render () { |
检测 include 与 exclude属性匹配的函数很简单,include 与 exclude 属性 支持字符串如”a,b,c”这样组件名以逗号隔开的情况以及正则表达式。matches通过这两种方式分别检测是否匹配当前组件。
1 | /* 检测name是否匹配 */ |
- 根据 key 在this.cache中查找,如果存在则说明之前已经缓存过了,直接将缓存的vnode的组件实例覆盖到目前的vnode上面
- 否则将 vnode 存储在 cache 中,再返回 vnode
1 | if (this.cache[key]) { |
watch
- 用 watch 来监听 include 与 exclude 这两个属性的改变,在改变的时候修改cache缓存中的缓存数据
1 | watch: { |
- 遍历cache中的所有项,如果不符合filter指定的规则的话,则会执行pruneCacheEntry
- pruneCacheEntry则会调用组件实例的$destroy方法来将组件销毁
1 | /* 修正cache */ |
总结
Vue.js内部将DOM节点抽象成了一个个的 VNode节点,keep-alive 组件的缓存也是基于VNode节点的而不是直接存储DOM结构
它将满足条件(include与exclude)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点 从 cache对象中 取出并渲染