Vue3 Reactive响应式原理是什么
时间:2023-05-22 02:44
怎么实现变量变化,相关依赖的结果也跟着变化 当原本 如果需要重新计算,我们需要将 来,试一下: 实现了变量 下一步,我们要解决的问题是:应该怎么把 怎么实现变量变化,变量改变后就取出effect执行 用什么存储 ????,解耦之后代码结构更清晰了。 下面需要解决的一个问题:一个object通常有多个属性,比如 因为不同的属性名有自己对应的 ????,一个object的多个属性依赖问题解决,更具有通用性了。 下一个问题是:不可能只有一个对象,多个对象又怎么办? 这里用 ????,到这里已经基本实现了通用性的响应式代码了,但是还有最后一个问题就是:我们的代码都需要手动执行(自己添加 通过Reflect和Proxy解决自执行问题 在JavaScript中,自动检测变量不就是 正是因为这样, 稍微封装一下我们的函数,名叫 ????,至此,Vue3基本的响应式原理就解析完了。 前面的代码都是判断各种情况,我们就看最后几行 可以看到 在 我们看一下 以上就是Vue3 Reactive响应式原理是什么的详细内容,更多请关注Gxl网其它相关文章!一、怎么实现变量变化
price=5
变为price=20
后total
应该变为40
,但是实际total
并不会改变。 解决办法可以这样,当变量改变了,重新计算一次,那么结果就会改变为最新的结果。total
语句存储为一个函数,才能实现依赖的变量改变就进行一次依赖项计算。这里就用effect
表示函数名。price
改变,依赖变量price quantity
的变量total
也发生改变。effect
存储起来,让代码更加有通用性,而不是一直复写effect
,分离出其他的功能的函数各司其职,也就是大家常说的解耦。二、怎么实现变量变化
effect
呢?当然是用Set,因为Set会过滤出重复的元素,所以能够保证存储在Set中的函数不是重复的。 这里定义一个存储effect
依赖的变量为dep = new Set()
,定义track
函数表示存储的过程。 定义trigger
函数用以取出dep
中相关的effect
函数执行(这里定义的函数与Vue3源码同名同意义)。effect
: 会影响结果的函数(要实现响应式的依赖语句)track
:保存所有的effecttrigger
: 当变量改变重新执行代码product = { price: 5, quantity: 2 }
,在保存依赖时只创建了一个dep
的集合,应该给price
和quantity
都创建dep
,因为total
的最终结果依赖这两个属性,其中任何一个改变都要触发trigger
函数。创建了两个dep
就需要一个容器将dep
存储起来。三、将多个dep存储在Map中
dep
,所以我们用Map结构(键值对形式)来保存不同dep
。let product = { price: 5, quantity: 2 }
let user = { firstName: "Joe", lastName: "Smith" }
,比如两个对象的时候就需要进一步修改上面的代码了。四、将多个object的depsMap继续存储起来
WeakMap
数据结构去存储多个需要响应式的object的depsMap
。WeakMap
的基本使用和Map
差不多,只不过WeakMap
只接受对象为键值,而depsMap
是一个Map
结构刚好(必须是)是对象类型。targetMap
作为存储多个depsMap
的容器名。trigger
运行),不能自动运行。怎么让它能够自动检测变量改变,然后自动修改结果呢?五、核心
get
、自动修改变量不就是set
吗?在Vue2.x版本中用ES5的Obeject.defineProperty()
自带的getter/setter
去解决这个问题。ES6中Proxy
也能解决这个问题,但是Proxy
不兼任IE浏览器,当时大家还讨论过说不知道尤大怎么去考虑这个问题,现在问题的答案就是——不考虑。也就是根本不考虑IE兼不兼容????????。Proxy
就是代理的意思,任何对真实数据的操作它都能拦截并且代理操作,也就是说Object
上一些能实现的方法,Proxy
也能实现。Proxy
使用语法是new Proxy(target, hanler)
,handler
是你想实现什么样的代理功能配置。 而Reflect
就更神奇了,它的作用是取代Object
类上的一些方法让Obeject
类更纯粹的代表一个类,不要附加太多方法在上面,比如a in obj
表示判断obj
中是否有a
,在Reflect
中用Reflect.has(a)
比较语义化的方式就可以代替之前的方法。Proxy
和Reflect
就对应上了,都有Object
上的方法。 具体关于Reflect
和Proxy
的语法可以参考阮一峰大大的 ES6入门教程。Reactive
六、源码解析(TypeScript)
return
了createReactiveObject
函数,所以去看createReactiveObject
。const observed = new Proxy( target, collectionTypes.has(target.constructor) ? collectionHandlers : baseHandlers )
Proxy
的handler
为collectionHandlers
或者 baseHandlers
,继续选择一个看一看。baseHandlers
中可以看到导出了get/set/deleteProperty
等属性配置:set
: