不进行深度观测的我们在initRender函数中见过:
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
!isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
}, true)
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
!isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
}, true)
在Vue实例上定义属性$attrs和$listeners时就是非深度观测。
在get中收集依赖
接下来就是使用Object.defineProperty设置访问器属性,先看一下get函数:
get: function reactiveGetter () {
const value = getter ? getter.call(obj) : val
if (Dep.target) {
dep.depend()
if (childOb) {
childOb.dep.depend()
if (Array.isArray(value)) {
dependArray(value)
}
}
}
return value
},
get函数首先是要返回属性值,还有就是在这里收集依赖。
第一行代码就是获取属性值。先判断了getter是否存在,getter就是属性原有的get函数,如果存在的话调用该函数获取属性值,否则的话就用val作为属性值。
接下来是收集依赖的代码:
if (Dep.target) {
dep.depend()
if (childOb) {
childOb.dep.depend()
if (Array.isArray(value)) {
dependArray(value)
}
}
}
首先判断Dep.target是否存在,Dep.target就是要收集的依赖,如果存在的话,执行if语句块内的代码。
dep.depend()dep对象的depend方法执行就是收集依赖。
然后判断了childOb是否存在,存在的话执行childOb.dep.depend(). 那么childOb的值是谁呢?
如果我们有个数据对象:
data = {
a: {
b: 1
}
}
经过observe观测之后,添加__ob__属性,变成如下模样:
data = {
a: {
b: 1,
__ob__: { value, dep, vmCount }
},
__ob__: { value, dep, vmCount }
}
对于属性a来说,childOb === data.a.__ob__, 所以childOb.dep.depend()就是data.a.__ob__.dep.depend()
在if语句里面又一个if判断:
if (Array.isArray(value)) {
dependArray(value)
}
如果属性值是数组,调用dependArray函数逐个触发数组元素的依赖收集
在set函数中触发依赖
set: function reactiveSetter (newVal) {
const value = getter ? getter.call(obj) : val
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
/* eslint-enable no-self-compare */
if (process.env.NODE_ENV !== 'production' && customSetter) {
customSetter()
}
// #7981: for accessor properties without setter
if (getter && !setter) return
if (setter) {
setter.call(obj, newVal)
} else {
val = newVal
}
childOb = !shallow && observe(newVal)
dep.notify()
}
内容版权声明:除非注明,否则皆为本站原创文章。

