提问
使用 Vue3 中,我们最常使用的就是 reactive
和 ref
。但是我们有时候会觉得为什么使用 ref
的时候,需要每次通过 value
属性来改变值,而使用 reactive
的时候,一定要是一个对象,今天我们来讲解一下其背后的设计原理。
DefineProperty
使用 Vue2 的同学们都知道,Vue 的属性双向绑定是通过 Object 的 DefineProperty
实现的,那这个设计思想其实也是有延续到 Vue3 的,这也就是为什么 Vue3 中的 ref
要通过 value
属性来进行赋值。因为一个单一的 primitive 变量是不具备属性的监听和拦截,但是一个 Object 可以通过 DefineProperty
来进行属性的拦截,当我们为一个 Object 的属性进行 set
和 get
的时候,我们可以通过拦截,进行 side effect。这也就是为什么 ref
需要有一个 value
属性。虽然我们在使用 ref
的时候,都是传入 primitive value,也就是基础类型,比如 boolean
, number
或者 string
,但是背后都是依托于 Object 来进行响应式赋值,并且 value
属性本身是不被 return,也就是说,我们不会去使用 value
属性,这个属性创建了一个我们可以拦截的桥。但在 Vue3 中,已经使用 Proxy 来进行对象数据的拦截功能。
Proxy
再来说一下 reactive
为什么一定要是对象,其原理是通过 Proxy 来实现 reactive
的响应式,我们传入的 reactive
的初始值是作为 Proxy
的 target,而 Proxy
的 handler 则是实现的真正操作。
以上,就是 ref
和 reactive
设计思路,大家也可以去仔细看一下 Proxy
的使用方法,