【学习笔记】Vue3源码解析:第二部分-实现响应式(3)

课程地址:【已完结】全网最详细Vue3源码解析!(一行行带你手写Vue3源码)

第二部分-实现响应式(3):(对应课程的第10-14节)

第10节:《定义收集依赖的effect方法》

vue3中的effect相当于vue2中的watcher。

一、在源码中使用effect方法

1、首先,在源码的vue/examples下,新建2.effect.html文件,在其中使用effect方法:
在这里插入图片描述
在这里插入图片描述

总结:effect函数的作用:它是一个会默认自动执行的方法,当在视图中获取数据时,会触发代理对象的get,此时会进行收集effect;当修改数据时,会触发响应式对象的set,此时执行对应的effect。

在这里插入图片描述

effect方法的第二个参数可以传递一个配置对象,当配置lazy:true时,effect不会默认执行:

在这里插入图片描述

二、实现effect方法

2、在reactivity下新建effect.ts文件,在其中暴露effect方法:
在这里插入图片描述

3、在入口文件中引入并暴露effect方法:

在这里插入图片描述

4、编写effect方法:它接收一个函数fn,以及一个配置对象options。其函数体内定义一个函数并返回,且判断options的lazy属性不为真时,该函数会被执行。该函数是由一个createReactiveEffect函数生成的,这个函数接收了外层函数的入参fn和options作为自己的入参:

createReactiveEffect函数内部逻辑为:返回一个方法,并将其保存在effect变量中;这个方法会执行用户传递给effect的方法,即fn入参:
在这里插入图片描述

5、测试刚刚编写的effect方法:examples下新建文件2.effect.html

在这里插入图片描述

浏览器打开2.effect.html,可以看到控制台打印了500

第11节:《定义栈结构》

1、为effect添加属性:
为什么要为effect添加属性?因为收集effect的目的是为了更新视图,当读取响应式对象的属性A和属性B时,这两个属性分别对应各自的一个effect,它们对应的各自的effect是不一样的,所以需要区别。
在这里插入图片描述

2、在createGetter中,获取数据时,添加收集effect逻辑:

在这里插入图片描述

3、新建operations操作符文件,在其中定义操作符:

在这里插入图片描述

4、引入操作符文件,并在get中读取数据时进行收集effect时,调用Track方法,入参分别为:target(目标对象)、操作符类型,此处为get,key(读取的对象的属性)

在这里插入图片描述

5、在effect.ts中定义Track方法。在全局定义activeEffect,保存effect,并传递到Track方法里:

在这里插入图片描述

6、打印结果如下:

在这里插入图片描述

7、解决一个嵌套的问题,如下代码,effect方法里,又嵌套了一个effect方法,用一个栈形结构来处理这个问题:

在这里插入图片描述

在这里插入图片描述

第12节:《收集effect依赖》

1、当某个属性被重复读取时,如state.a,此时收集的仍然是其对应的那一个effect,不需要重复收集:

在这里插入图片描述

增加 if 判断:

在这里插入图片描述

2、在Track方法中收集effect:定义一个WeakMap结构,保存到 targetMap 变量中,首先判断 targetMap 中之中是否已经保存过了 target 这个值,如果没有则将其保存进去,将target(即用户传给响应式API的目标对象)设置为键,new 一个Map结构设置为其对应的值。

在这里插入图片描述

在这里插入图片描述

在 effect 中读取响应式对象的属性name时:

在这里插入图片描述

查看控制台打印出来的 targetMap :

在这里插入图片描述
可以看到其结构为:首先它是一个 weakMap 结构,其键为target对象,值为一个Map结构,这个Map结构中,键是被访问的target的属性name,值是一个Set结构,这个Set结构中,存放着effect方法

在这里插入图片描述

当在 effect 中使用 name 和 age 时:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

分别在两个effect中使用name时:

在这里插入图片描述

在这里插入图片描述

第13节:《判断数组是否新增还是修改》

vue3与vue2实现响应式还有一个不同的点是:vue3用proxy实现响应式可以直接实现对数组的代理,不需要像vue2一样劫持数组的方法去进行改写

1、在shared中增加几个公共方法:

在这里插入图片描述

2、baseHandlers中引入这些公共方法,并在 createSetter 方法中添加如下逻辑:首先存储旧值;然后判断目标对象是数组还是对象,如果是数组且其访问的key值小于数组长度,即读取的数组已有项;如是对象则判断对象是否有被访问的这个属性key,如有则是访问对象的一个已有值。这样就可以区分是为目标对象新增一个key值还是访问目标对象的已有值。

在这里插入图片描述

第14节:《总结知识点及面试题》

本节课基本没啥知识点

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值