get方法mutableHandlers速览(2)

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展开!
本人菜鸡,有问题望前辈及时指出,不胜感激!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容