浅谈 vue3 响应式原理 第一篇 响应式和副作用
浅谈 vue3 响应式原理 第一篇 响应式和副作用
一年前,在开课吧的视频里看到 winter、大圣还有尤大吹嘘着 vue3,各种新名词映入眼帘:watchEffect,reactive,ref,当时觉得好牛逼啊,一定要学一下(咕咕咕)。
一年后,watchEffect 是啥,reactive 是啥,ref 又是啥,怎么多了出了这么多东西,好难啊,趁现在赶紧摸索清楚。
副作用
我们经常能在尤大口中听到一个词: sideEffect
。首次听这个词时,我也是一头雾水,副作用到底是什么,吃药时的副作用吗?在尤大在评论 winter 的小案例时,他讲了 winter 在组件销毁时没有清理掉之前设置的事件监听器,这会对程序产生副作用。当然,尤大此时说的是 sideEffect
是另一个方面的。
vue3中的 sideEffect
怎么理解?一些变量执行某些基本操作时,被拦截并执行一些事情,这些事情叫 sideEffect
。
拦截
上面说到拦截,这是 vue 经常做的事情。vue 就喜欢在变量读取、写入的时候拦截并做操作。
在 vue2 中,尤大是通过 Object.defineProperty
给变量设置存取器属性,然后在存取器中执行副作用。到了 vue3,尤大用了 es6 的新特性 Proxy
和 Reflect
重写了这部分的代码。Proxy
提供了对变量基本操作的各种拦截回调,Reflect
则是对这些基本操作的实现。通过 Proxy
,将变量的基本操作修改为副作用+基本操作,完成副作用的执行。
响应式
响应式是什么
要明白响应式是什么,我们通过下面几行代码讲解
1 | let product = { |
上面代码表明了 total 是由 price 和 quantity 计算得出,但是当我们修改了 quantity 后,total 的值却没有跟着变,因此我们知道原生的 javascript 是没有响应式的
那么要怎么实现响应式
1 | let product = { |
我们发现,如果我们将 total 的计算方式保存为一个函数,然后在每次更新 quantity 之后调用一次,total 的值就会跟着变化。
那么只要我们在quantity更新时自动执行 trigger
,响应式就实现了。
自动?
要实现自动,我们就需要前面讲到的知识:拦截。
我们通过 Proxy
,在 quantity 执行 set
操作时进行拦截,然后将上述 trigger
添加为 set
操作的副作用。
1 | let p = { |
这下我们可以在 set
操作时自动执行 trigger
了
未完持续O(∩_∩)O