Vue3|Vue3 KeepAlive实现原理解析
目录
- 思路
- 代码解析
- setup
- render
- onActivated 和 onDeactived调用
思路 首先我们知道
KeepAlive
是一个内置组件,那封装一个组件对于大家来说应该不会有太大的困难,它的核心逻辑在于它的 render 函数,它用 map 去记录要缓存的组件,就是 [key,vnode]
的形式。它的核心思想就是 LRU
,当我们限制有 maxSize 的时候,超过 maxSize 时我们会删除最久没有使用的[key, vnode]
,可以看看 leetcode146.LRU缓存;基本上你理清了 LRU 算法的思路,keepalive
的原理你也知道的差不多了。代码解析 我只贴出来能帮助大家理解的核心代码,源码位于
core/package/runtime-core/src/components/KeepAlive.ts
setup
const cache: Cache = new Map()const keys: Keys = new Set()// cache sub tree after renderlet pendingCacheKey: CacheKey | null = nullconst cacheSubtree = () => {// fix #1621, the pendingCacheKey could be 0if (pendingCacheKey != null) {cache.set(pendingCacheKey, getInnerChild(instance.subTree))}}// 组件挂载和更新的时候就会缓存最新的组件onMounted(cacheSubtree)onUpdated(cacheSubtree)
render
tips
:这块逻辑就是 setup 的返回值const comp = vnode.type as ConcreteComponentconst key = vnode.key == null ? comp : vnode.keypendingCacheKey = keyconst cachedVNode = cache.get(key)// tips: keys 仅仅是用于收集组件的 key 组件实际收集在cache中if (cachedVNode) { // 节点存在缓存中// copy over mounted state(复制过去的状态)vnode.el = cachedVNode.elvnode.component = cachedVNode.component// 将节点放到队尾keys.delete(key) keys.add(key)} else { // 不存在keys.add(key) // 加入缓存队列// prune oldest entry// 超过最大值了,将最久没有使用的组件删除,也就是队头组件if (max && keys.size > parseInt(max as string, 10)) { pruneCacheEntry(keys.values().next().value)}}
onActivated 和 onDeactived调用
tips:这两块逻辑是在 diff 中,看不懂没关系,只要注意一个点就是被缓存的组件节点有一个标识
ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
,我们在挂载组件的时候和卸载组件的时候判断一下是否有这个标识,有就去调用 onActiveated 或 onDeactived;源码位于:core/package/runtime-core/src/renderer
if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {; (parentComponent!.ctx as KeepAliveContext).deactivate(vnode)return}if (initialVNode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE ||(parent &&isAsyncWrapper(parent.vnode) &&parent.vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE)) {instance.a && queuePostRenderEffect(instance.a, parentSuspense)if (__COMPAT__ &&isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance)) {queuePostRenderEffect(() => instance.emit('hook:activated'),parentSuspense)}}
【Vue3|Vue3 KeepAlive实现原理解析】到此这篇关于Vue3 KeepAlive实现原理的文章就介绍到这了,更多相关Vue3 KeepAlive原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 毕设教程|【毕设教程】退火算法路径优化实现
- redis|springboot使用redisTemplate+websocket实现集群消息的发布订阅
- netty|基于Netty实现websocket集群部署实现方案
- 朴素贝叶斯分类器python_python实现高斯朴素贝叶斯分类器
- 朴素贝叶斯分类器python实现_python|朴素贝叶斯分类器python实现_python 实现朴素贝叶斯分类器(离散数据)
- C++|C++s简单实现Scoket编程
- springBoot|SpringBoot+flowable快速实现工作流
- 中间件|Spring Boot + flowable 完美结合,快速实现工作流
- springboot+flowable实现工作流
- springboot相关|java短信验证码登录功能设计与实现