reactive
类的 api 主要提供了将复杂类型的数据处理成响应式数据的能力,其实这个复杂类型是要在object array map set weakmap weakset
这五种之中(object 指的是 {}),在调用 reactive
类 api 处理数据时,有一个判断以下vue
if (!canObserve(target)) {
return target
}
// 下面是 canObserver 的实现
const canObserve = (value: Target): boolean => {
return (
!value[ReactiveFlags.SKIP] && // 表示这个对象须要跳过,不能再进行 reactive 的响应式处理。好比自定义组件
isObservableType(toRawType(value)) &&
!Object.isFrozen(value) // 这个对象没有被 Object.frozen() 处理过,被处理过的在非严格模式下的赋值不会报错,可是不成功
)
}
复制代码
分析以下:react
value[ReactiveFlags.SKIP]
:ReactiveFlags.SKIP
的值为 '__v_skip'
表示有此属性的值就不能转换为响应式数据,你能够本身手动给你不想转换的数据添加此属性,就会使数据必能进行响应式变换(不建议你这么作,通常自定义组件会有这个属性)。api
isObservableType(toRawType(value))
: 这个语句相对复杂一些,能够拆开来看bash
a. toRawType(value)
: 这个方法是获取传入值得原始类型,好比 [] ===> Array
这个类型的获取是经过 Object.toString.call(target)
获取,而后截取的。 b.isObservableType
就是判断是不是 object array map set weakmap weakset
其中的一种,若是是就符合要求能够建立,这样子的限制也说明了 vue3 但愿你是真正的想使某种数据结构变为响应式时才使用 reactive
类的 api,而不是什么数据都是进行转换。数据结构
vue3 提出了 readonly
数据,表示数据只可读,不了修改;因此,响应式处理的 api 通常是两个版本:普通版本 和 readonly 版本。注意,这两种数据时互斥的,也就是不能互相转换,也不能同时拥有两种类型。ui
一个是普通的响应式版本,一个是 只读的版本,根据须要取用。
注意: 这两个 api 会对数据进行深层次的处理,若是属性时对象,依然会处理成响应式的数据,这一点区别于下面的两个 apispa
钱响应的版本,一个是普通的响应式版本,一个是 只读的版本,根据须要取用。code
上面两组 api 能够理解为第一组是深拷贝,第二组是 浅拷贝server
这里的判断 api 就是其表面的语义。这里只作列举不会深刻研究,会在下一节研究 vue3 使用 proxy
设置 set
和 get
中详细分析。对象