🗒️vue3源码学习-4-effect编写以及依赖收集
2022-6-8
| 2024-3-22
0  |  阅读时长 0 分钟
date
icon
password
description
permalink
categories
type
status
slug
summary
tags
category
updated
Mar 22, 2024 09:10 AM

前言

经过上文的响应式编写之后,实现了数据包裹之后变成了响应式数据,用户修改数据的时候能监听到操作。
但是实际编写的响应式reactive.ts中最核心的是Proxy中的get和set方法。为此我们本次需要将核心代码抽离,并且编写effect副作用函数和依赖收集功能,这样函数依赖发生改变,他就重新执行。

reactive.ts核心代码抽离

响应式代码最重要的式get和set函数,那么对这一块逻辑抽离。并命名为baseHandles.ts,然后抛出。
然后在reactive.ts中把抽离的代码引入进去
注意这里出现的一个循环引用逻辑,但是这个不会再ES6中造成问题。reactive.ts中引入了baseHandles.ts,但是reactive.ts中对对象的代理包裹,我们应用了reactive.ts,并且包裹了数据,当数据改变的时候,就会触发set,而这个时候baseHandles.ts又依赖到了reactive.ts。造成了循环引用,但是这个不会导致任何的问题出现。

effect功能的编写

在测试官方代码的时候,是这么操作effect的。effect(() =>{document.getElementById("app").innerHTML = state.name+'今年'+state.age})
通过对上面的操作分析,可以知道通过effect运行了它里面的回调函数,也就是执行了渲染一个谁今年多少岁的一段文字。当被effect包裹的回调函数中state.namestate.age参数改变的时候,我们还要更新下这一段文字。所以有了当前的effect对应这个stage上的nage和age的映射关系。
再往深处思考,也会出现这种代码effect(() => {stage.name;effect(() => {stage.age})}),这种嵌套的写法,这就是组件的写法了。
上面的实例代码中外层effect1可以对应上stage.name,而里面的effect2对应上了stage.age。执行到当前的effect上的时候就能找到对应关联的属性。
所以我们需要这么一个操作,对象的属性->effect,而且如果一个属性可能在多个effect,那么对象作为key,最好的是自然就是WeakMap了,它还有个好处就是,当value为空的时候,垃圾回收机制对它进行回收。
那么对上面对思路进行整合,得出我们需要一个这样对数据结构{对象:Map{name:Set}}。那么现在来编写一下effect.ts,完成里面的依赖收集和属性改变的时候触发再次运行的函数。
上面的代码除了基础的分析之外,还有对3.0初期如何找到当前的effec的2种做法之外,还解决了模版渲染的时候又触发了run函数,导致循环调用的问题。
那么上面的主要代码解释了收集依赖的过程,那么现在要对baseHandles.ts做一个依赖收集的入口。
baseHandles.ts编写如下
## 结尾
到目前为止,完成了所需要做的工作,这个时候可以在index.html上引入编写好的effect功能,先运行项目
npm run dev,然后倒入编译好的文件。从对象中获取编写的功能
  • Vue
  • TypeScript
  • vue3源码学习-5-分支切换Http和Https学习(一)
    • Waline
    目录