先了解一下概念
主要是提供了这么几个对象
- reactive
- readonly
- shallowReactive
- shallowReadonly
- markRaw 返回对象
- toRaw 返回对象
然后提供了这么几个工具
- isReactive
- isReadonly
- isProxy
- markRaw
- toRaw
首先理解他们之间的关系:
reactive and shallowReactive
reactive
可以响应数据,就是说get
和set
都可以干一些事情的数据,是深响应,也就是说对标shallowReactive
是浅响应,他俩的区别主要是浅响应只劫持一层。
reactive and toRaw
像这样
const obj = {}
const reactived = reactive(obj)
const row = toRaw(reactived)
// row === obj
也就是取响应的数据的原始数据
reactive and markRaw
标记一个对象,使其永远不会转换为响应数据,即不可代理的数据。
readonly and shallowReadonly
readonly
可以让一个响应数据只读,readonly
和 shallowReadonly
的关系就象reactive
和 shallowReactive
一样,他俩的区别主要是浅响应只劫持一层。
readonly and reactive
给出一段文档示例,除了不能set,其余的都一样
import { reactive, isReactive, readonly } from 'vue'
export default {
setup() {
const state = reactive({
name: 'John'
})
// readonly proxy created from plain object
const plain = readonly({
name: 'Mary'
})
console.log(isReactive(plain)) // -> false
// readonly proxy created from reactive proxy
const stateCopy = readonly(state)
console.log(isReactive(stateCopy)) // -> true
}
}
readonly 普通对象
他就是不是一个响应对象
readonly 响应对象
他就是一个响应对象,并且响应对象改变,会触发readonly
的监听,同样值可以变。这可能就是为什么叫readonly
而不是disable
。
梳理逻辑
标记
其实这些对象都是响应或者不响应的对象,最重要的就是该不该响应和怎样响应的问题。
SKIP
带有这个标记的就是不应该响应的,如markRaw
IS_REACTIVE
带有这个标记的就是响应数据
IS_READONLY
带有这个标记的就是只读数据
RAW
这个不是标记,用于取原始对象,如toRow
,但是并不一定是最原始的对象,如readonly
的原始对象可能是响应对象。
REACTIVE
用于存放响应对象,也就是说如果该数据被响应过就直接返回结果
READONLY
同上,存放只读对象
工具函数
有了标记,思路就比较清晰了
isReactive
有IS_REACTIVE
标记的
isReadonly
有IS_READONLY
标记的
isProxy
有IS_READONLY
或者IS_REACTIVE
标记的
markRaw
添加一个SKIP
标记
toRaw
取RAW
存放的数据
公共部分与柯里化
前面提到重要的就是该不该响应和怎样响应的问题。所以要有一个可以决定该不该响应和怎样的响应的函数,在源码中是createReactiveObject
还需要做决定返回什么样的对象。
检查数据
目标不是对象的
直接返回目标
目标已经处理过的
直接返回处理过的对象
对象不允许被响应的
返回对象本身
代理数据
不同的对象提供不同的get
和set
。
collectionHandlers
由 Object,Array,Map,Set,WeakMap,WeakSet 构造的
baseHandlers
上面取反
最后
在写wxue响应部分,看了@vue/reactivity
的源码,并把他记录下来。顺便把reactive
部分切换成@vue/reactivity
,不再是重复造轮子,因为Vue3.x分包后更加独立。如果你想在小程序中体验Vue3.x的composition-api
,赶快安装wxue试一试吧,如果可以的话点下star那就更完美了。