聊聊vue中的keep-alive

554 阅读3分钟

大家好,这是一个更文挑战。这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

1. keep-alive特点

  1. 首先它vue内置抽象组件

  2. 其次 被 keep-alive标签包裹动态组件时, 会缓存不活动的组件实例,而不是销毁它们

  3. 自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中(看过源代码的同学应该知道,有个abstract用来判断当前组件虚拟dom是否渲染成真是dom,true的话是不会渲染成真正的dom的)

注: vue的虚拟dom,经过diff算法,生成真实dom上树的原理,其实是借鉴了snabbdom,感兴趣的同学可以到github阅读源码:snabbdom源码

  1. activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

2. keep-alive组件的Props

  1. include(一个正则表达式): 定义缓存白名单,keep-alive会缓存命中的组件

  2. exclude(一个正则表达式): 定义缓存黑名单,被命中的组件将不会被缓存

  3. max: 定义缓存组件上限,超出上限使用LRU 的策略置换缓存数据

注: LRU:Least Recently Used(最近最少使用算法) ,经常会被用在缓存相关的设计里面

一个LRU生活场景: 你有一个收纳盒,收纳盒最多只能放10双袜子,但是你最近新买了一双,也想放进去,这时候怎么办? 那就是把你最不常穿的那双扔掉。

这个收纳盒就相当于 缓存的容量只有10kb,这时候你要存11kb的东西,那就要把最不长用的从缓存里面清除

3. 源码

源码地址:github.com/vuejs

这里就不粘贴keep-alive相关的源代码了,感兴趣的同学,自行阅读

下面就总结下keep-alive是怎么实现缓存的具体过程

  • 第一步:获取keep-alive包裹着的第一个子组件对象及其组件名 (可以在源代码中找相应代码)

  • 第二步:根据设定的黑白名单(如果有)进行条件匹配,决定是否缓存。不匹配,直接返回组件实例(VNode),否则执行第三步;(源码中有对应体现

  • 第三步:根据组件ID和tag生成缓存Key,并在缓存对象中查找是否已缓存过该组件实例。如果存在,直接取出缓存值并更新该key在this.keys中的位置(更新key的位置是实现LRU置换策略的关键),否则执行第四步;(源码中有对应体现

  • 第四步:在this.cache对象中存储该组件实例并保存key值,之后检查缓存的实例数量是否超过max设置值,超过则根据LRU置换策略删除最近最久未使用的实例(即是下标为0的那个key);(源码中有对应体现

  • 第五步:最后并且很重要将该组件实例的keepAlive属性值设置为true。(源码中有对应体现

上面的每一个步骤在源码中都有对应的体现,一定要去看源码哦, 一起加油鸭