mutableHandlers对象包含get、set、deleteProperty、has、ownKeys这几个key值,本章主要关注get对应的值。
get对应的是createGetter函数,此函数接受两个参数(isReadonly/shallow),这两个参数默认为false,mutableHandlers采用的是默认传值
方法体如下:
1.如果访问的是__v_isReactive对象属性,则返回!isReadonly,即true
如果访问的是__v_isReadonly对象属性,则返回isReadonly,即false
如果访问的是__v_isShallow,则返回shallow,即false
如果访问的是__v_raw,reactiveMap映射中存在该对象的映射,则直接返回该对象映射(之前代理过)
if (key === ReactiveFlags.IS_REACTIVE) {
return !isReadonly
} else if (key === ReactiveFlags.IS_READONLY) {
return isReadonly
} else if (key === ReactiveFlags.IS_SHALLOW) {
return shallow
} else if (
key === ReactiveFlags.RAW &&
receiver ===
(isReadonly
? shallow
? shallowReadonlyMap
: readonlyMap
: shallow
? shallowReactiveMap
: reactiveMap
).get(target)
) {
return target
}
2.如果访问的是数组,属性是(includes/indexOf/lastIndexOf)或者(push/pop/shift/unshift/splice),则走改写的数组方法arrayInstrumentations(下文产开)
if (!isReadonly) {
if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver)
}
if (key === 'hasOwnProperty') {
return hasOwnProperty
}
}
3.如果访问的是hasOwnProperty属性,则走hasOwnProperty这个方法
function hasOwnProperty(key: string) {
// @ts-ignore
const obj = toRaw(this)
track(obj, TrackOpTypes.HAS, key)
return obj.hasOwnProperty(key)
}
4.如果访问的属性值是symbol类型或者proto,__v_isRef,__isVue,则直接返回对象的值,不进行依赖收集
const res = Reflect.get(target, key, receiver)
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
return res
}
5.如果函数参数shallow值为true,则直接返回对象值,依赖收集到此停止,不再深入收集
if (shallow) {
return res
}
6.如果对象属性值是ref类型,对象是数组,key是整数的,则直接返回属性值,不进行unRef,对象是数组之外的,则返回ref原始值(.value),依赖收集到此为止
if (isRef(res)) {
// ref unwrapping - skip unwrap for Array + integer key.
return targetIsArray && isIntegerKey(key) ? res : res.value
}
示例如下:
import { ref, reactive } from 'vue';
const num = ref(1)
const arr = [num, 2, 3]
const obj = reactive({ num })
console.log(arr[0]) // Ref<1>
console.log(obj.num) // 1
7.如果对象属性值还是对象,则进一步深入进行依赖收集
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res)
}
下文对本文提到的改写数组方法arrayInstrumentations展开!
本人菜鸡,有问题望前辈及时指出,不胜感激!!