keep-alive组件解析
Function
工具函数
- pruneCacheEntry
- pruneCache
- matches
流程
总结
1.首先keep-alive是个内置组件,在初始化全局API时注册到全局组件中,keep-alive组件与普通组件的写法不同点是,普通的组件都是用template去写模板然后编译的,而keep-alive是直接写render函数。而且创建的是一个抽象的组件。在确定父子关系的时候是不去确立的简单来说就是不会创建实体节点。
2.对于keep-alive的props属性有三个参数include(需要使用Keep-alive的组件),exclude(不需要使用Keep-alive的组件),max(最多可以缓存多少组件实例)。
3.对于keep-alive的create钩子创建了cache缓存对象和keys缓存key的数组。
4.对于keep-alive的destroyed钩子调用了工具函数pruneCacheEntry这里遍历删除所有的cache和keys。
5.对于keep-alive的mounted钩子这里监听了include和exclude的变化对应调用了工具函数pruneCache,pruneCache主要是说include变了 此前存在 此后不存在 应该删除对应的cached和keys,exclude变了 此前不存在 此后存在 应该删除对应的cached和keys。
6.对于keep-alive的render,首先拿到keep-alive包裹内容的第一个组件节点,接着获取组件名称,通过工具函数matches匹配include与exclude,如果是不需要缓存的就直接返回组件vnode不作任何处理。
7.如果需要缓存的,首先获取组件的key,对于首次执行会把组件vnode添加到cache对象中缓存起来,接着往keys数组push key。如果定义了max,当key超出max会对缓存进行清理,这里使用了LRU的思想下面在说。紧接着就是为组件vnode.data设置keepAlive属性为true,最后返回这个组件。
8.对于二次渲染执行那么就会在cache中命中缓存,直接从缓存中取组件vnode。接着从keys数组中删除此key,将key添加到keys数组的最后面。紧接着就是为组件vnode.data设置keepAlive属性为true,最后返回这个组件。
9.当key超出max会对缓存进行清理,这里会调用工具函数pruneCacheEntry传入参数最终目的是删除keys数组中的第一个key以及cache对应的内容。删除第一个是什么概念呢,创建组件时候一直push进入Keys,如果数据最近被访问过,那么将来被访问的几率也更高,就把此key删除丢到keys数组最后面,所以第一个或者说前面的都是不经常访问的,所以删除。
LRU
LRU缓存管理策略思想:(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
1.新数据插入到链表头部;
2.每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
3.当链表满的时候,将链表尾部的数据丢弃。
初始化
template
ast
code
_render
_patch
patch流程
总结
第一次切换
patch流程
总结
第二次切换
patch流程
总结
总结
keep-alive组件是⼀个抽象组件,它的实现是通过⾃定义render函数并且利⽤了插槽,它对首次渲染的组件做缓存,首次渲会调用组件的create,mounted钩子,再次渲染时直接获取缓存中的组件vnode,不会执行组件的初始化,所以不会有⼀般的组件的⽣命周期函数。
对于activated 和 deactivated 钩⼦函数。我们知道patch最后执行两个逻辑一个是removeVnodes删除旧节点执行invokeDestroyHook,执行组件的deactivated。一个是invokeInsertHook遍历组件vnode队列,执行组件的insert钩子,执行组件的activated。
另外keep-alive的props 除了 include 和 exclude 还有的max ,它能控制我们缓存的个数涉及到了LRU思想。