【mini-vue】Reactive模块学习笔记

 前一阵子学习了mini-vue,回过头来看已经忘了七七八八,趁着周末重新复习一遍,留下笔记。

 mini-vue源码传送门:

cuixiaorui/mini-vue: 实现最简 vue3 模型( Help you learn more efficiently vue3 source code ) (github.com)https://github.com/cuixiaorui/mini-vue

目录

ReactiveEffect类

RefImpl类

ComputedRefImpl类

activeEffect公共变量

shouldTrack公共变量

reactive函数

ref函数

computed函数

readonly函数

shallowReadonly函数

effect函数

targetMap公共变量

track函数

trigger函数

stop函数

isReactive函数

isReadonly函数

isProxy函数

isRef函数

unRef函数

proxyRefs函数


ReactiveEffect类

  1. active: boolean

    初始值为true,用于判断是否执行过stop函数,当值为false,不再执行stop函数,防止重复调用cleanupEffect函数

  2. _fn: Function

    effect中传入的fn

  3. scheduler: Function

    effect的可选参数,如果scheduler有值,除了第一次effect函数会调用_effect对象的run方法,即执行effect中传入的fn,之后都会执行scheduler函数

  4. deps: Array

    用于存放该_effect对象中的依赖dep,dep中包含各种依赖fn

    值得注意的是,_effect对象与fn是多对多的关系

  5. opStop: Function

    effect函数的可选参数中传入的选项,当调用stop函数后会执行该函数

  6. constructor

    保存传入的fn和scheduler

  7. run: 类方法

    如果active为false则直接返回fn的执行结果

    将activeFn赋值为this,即该ReactiveEffect类创建出来的对象_effect

    调用用户在effect中传入的fn函数,并返回fn执行的结果

    在run开始结束前会通过开关shouldTrack来控制是否追踪收集依赖

  8. stop: 类方法

    调用该方法后会清除_effect对象中的所有dep中存入的this,即自己_effect对象,并清空deps数组

    active状态变为false

RefImpl类

  1. _value: any

    判断ref函数中传入的value是否为对象,如果是则用reactive包裹

  2. dep: Set

    存储依赖,一个dep对应一个value,因此只需要一个dep

  3. _rawValue: any

    ref函数中传入的value,因为ref函数中传入的value可能为对象,如果为对象需要用reactive包裹

  4. __v_isRef: boolean

    值为true,便于isRef函数的构建

  5. constructor

    保存传入的value,如果value为object对象,则应该用reactive包裹

  6. get value

    调用trackRefValue函数,当activeEffect值存在并且shouldTrack为true时,追踪收集 依赖,将依赖放置dep中

  7. set value

    首先判断新旧值是否改变,若改变则将_rawValue更新为newValue,如果是newValue是object则_value = reactive(newValue),否则_value = newValue

ComputedRefImpl类

  1. _dirty: boolean

    默认值true,控制缓存的判断依据

  2. _value: any

  3. _effect: object

    constructor中通过ReactiveEffect类创建出的对象_effect,并且在通过这个类创建对象时将getter作为第一个参数传入,传入scheduler函数,使得当set时trigger触发依赖,调用scheduler,将控制缓存的开关打开,即_dirty的值变为true,下一次get依旧会执行_effect.run()

  4. constructor

    初始化私有变量_effect,值得注意的是,不同于effect函数,这里并没有调用_effect.run()

  5. get value

    若开关_dirty打开,则说明_effect.run()需要重新执行,执行结果赋值给_value,并将开关关上,即下一次使用缓存

activeEffect公共变量

作用:保存当前处理的_effect对象,便于track中进行依赖的收集

来源:effect函数中通过ReactiveEffect类创建_effect对象,当调用_effect对象的run方法时,如果active为true,则将activeEffect = this,即将_effect赋值给activeEffect

shouldTrack公共变量

作用:默认值为false,用于判断是否追踪依赖,在ReactiveEffect的run方法中控制开闭

来源:调用stop后,当我们清除依赖后,可能会意外的重新收集依赖,例如调用代理对象某属性++,会先触发get再set,get中调用track,便会重新收集依赖,导致stop失效,因此需要在track函数调用后通过shouldTrack判断是否需要追踪收集依赖

reactive函数

参数:传入一个对象

返回值:返回代理的响应式对象

作用:

  1. 创建一个proxy代理对象

  2. get中劫持key,若key为常量IS_REACTIVE,则返回true,为isReactive函数提供支持

  3. get中对Reflect.get的返回值res进行判断,若res为对象则返回reactvie(res),即实现嵌套逻辑,将对象中的所有属性都代理为响应式对象

  4. get中调用track追踪收集响应式依赖

  5. set中调用trigger触发依赖

  6. 返回处理好的代理对象

ref函数

参数:any

返回值:返回一个通过.value访问值得对象

作用:通过RefImpl类创建对象并返回

computed函数

参数:Function getter

返回值:如果只传入getter返回一个有缓存、只读的ref对象

作用:返回通过ComputedRefImpl类创建的对象

readonly函数

参数:传入一个对象

返回值:返回一个只读对象

作用:

  1. 创建一个proxy代理对象

  2. get中劫持key,若key为常量IS_READONLY,则返回true,为isReadonly函数提供支持

  3. get中对Reflect的返回值res进行判断,若res为对象则返回readonly(res),同上,实现嵌套逻辑,将对象中的所有属性都代理为只读对象

  4. set中进行劫持,抛出警告,提示用户set失败,该对象为只读对象

  5. 返回处理好的代理对象

shallowReadonly函数

参数:传入一个对象

返回值:返回一个浅层只读对象

作用:返回一个浅层的readonly对象

effect函数

参数:

  1. fn

  2. 可选对象,可以传入scheduler、onStop等函数

返回值:通过ReactiveEffect类创建的_effect对象中的run方法

作用:

  1. 通过ReactiveEffect类创建的_effect对象

  2. 在_effect对象中添加对象的可选参数中的函数

  3. 调用_effect对象中的run方法

  4. 返回runner,即_effect对象中绑定了_effect对象为this的run方法,注意不是run方法的返回值而是run方法

  5. 给runner中绑定effect,便于后续stop方法的调用,即便于stop中调用effect中的stop

targetMap公共变量

作用:存储键为响应式对象,值为depsMap的键值对

track函数

参数:传入一个target对象和一个key对象的值

返回值:无

作用:

  1. 首先判断是否需要执行收集依赖,当activeEffect为空或shouldTrack为false则不需要收集依赖

  2. 从targetMap中获取depsMap,若depsMap为空说明要先初始化

  3. 从depsMap中获得dep,若dep为空说明要先初始化

  4. dep中添加activeEffect

  5. 在activeEffect的deps中添加dep

trigger函数

参数:传入一个target对象和一个key对象的值

返回值:无

作用:

  1. 从targetMap中获取depsMap

  2. 从depsMap中获取dep

  3. 遍历dep中的effect并触发对应的依赖(如果有scheduler则执行它,没有则执行run)

stop函数

参数:effect函数的返回值,即_effect对象中绑定了_effect对象为this的run方法

返回值:无

作用:执行runner.effect.stop()

isReactive函数

参数:any

返回值:布尔值

作用:访问这个对象的属性IS_REACTIVE,并将返回值返回,从而知道该对象是否为响应式对象,具体实现看reactive函数中的作用2

isReadonly函数

参数:any

返回值:布尔值

作用:访问这个对象的属性IS_READONLY,并将返回值返回,从而知道该对象是否为响应式对象,具体实现看readonly函数中的作用2

isProxy函数

参数:any

返回值:布尔值

作用:判断是否是reactive或者readonly对象

isRef函数

参数:any

返回值:布尔值

作用:访问__v_isRef属性,判断是否为ref对象

unRef函数

参数:any

返回值:返回实际值(如果是ref则返回ref.value,如果不是则返回本身)

作用:

  1. 如果是ref对象,则返回ref.value

  2. 如果不是ref对象,则返回本身

起源:有时候我们不知道想要访问的变量是否为ref对象,这个时候用该函数便能获取到想要的结果

proxyRefs函数

参数:any

返回值:便于template模板中使用的代理对象

作用:

  1. 创建代理对象

  2. 劫持get,返回unRef包裹的Reflect.get

  3. 劫持set,如果是ref对象并且newValue不是ref对象,target[key].value = newValue(当我们修改一个ref对象的时候,我们希望修改后的结果还是ref)

  4. 劫持set中,如果是其他情况,直接通过Reflect.set返回newValue

  5. 返回处理后的代理对象

起源:setup返回ref对象,在template中使用setup中返回的变量都默认需要通过proxyRefs包裹

如果本文对您有一丁点帮助,点个赞支持一下吧,感谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值