1. reactive

  • createReactiveObject

    • 该办法传入五个参数,分别为:

    • target: Target

      • 含义:这是要被转化成呼应式方针的原始方针。在 Vue 的呼应式体系中,任何能够被 Proxy 包装的 JavaScript 方针或调集都能够作为 target
      • 用处:这个参数是呼应式转化的直接方针,函数将根据这个方针方针创立一个呼应式署理。
    • isReadonly: boolean

      • 含义:这个布尔值指示创立的呼应式方针是否应该是只读的。
      • 用处:假如设置为 true,则署理将阻拦所有尝试修正方针方针的操作,并可能抛出正告或错误,阻止这些修正。
    • baseHandlers: ProxyHandler<any>

      • 含义:这是一个包含各种阻拦函数(如 get, set, deleteProperty 等)的方针,用于一般方针的呼应式处理。
      • 用处:这些处理器定义了对一般方针进行操作时的行为,例如怎么追踪依靠、触发更新等。
    • collectionHandlers: ProxyHandler<any>

      • 含义:这是一个专为处理 JavaScript 的调集类型(如 Map, Set, WeakMap, WeakSet 等)设计的阻拦处理器集。
      • 用处:调集类型由于其内部结构和运用办法的特别性,需求不同的阻拦逻辑来完成呼应式功用
    • proxyMap: WeakMap<Target, any>

      • 含义:这是一个 WeakMap,用于存储原始方针方针与其署理方针之间的映射。
      • 用处:经过这个映射,Vue 能够为同一个方针方针重复运用同一个署理,避免创立多个署理导致的内存泄漏和功能问题。同时,WeakMap 的运用保证了当原始方针不再被引证时,其署理方针也能够被废物收回,从而优化了内存运用。
    • 进入该函数:

      //判别传入的东西是否为方针,只有方针类型才能够,假如不是方针直接回来,假如是在开发环境中回来正告
      if (!isObject(target)) {
        if (__DEV__) {
         warn(`value cannot be made reactive: ${String(target)}`)
         }
        return target
        }
      //这儿的isObject
      export const isObject = (val: unknown): val is Record<any, any> =>
       val !== null && typeof val === 'object'
      
    • 持续进行查看

      // 假如方针已经是一个Proxy,回来
      // exception: calling readonly() on a reactive object
       if (
        target[ReactiveFlags.RAW] &&
        !(isReadonly && target[ReactiveFlags.IS_REACTIVE])
        ) {
        return target
        }
      //target[ReactiveFlags.RAW]:这个条件查看 target 方针是否具有 ReactiveFlags.RAW 标志。在 Vue 3 中,ReactiveFlags.RAW 标志用于存储原始方针的引证,通常在方针被转化成呼应式方针时设置。假如该特点存在,说明 target 已经是一个经过 reactive 或相似办法处理过的呼应式署理,其 RAW 特点指向未被署理的原始方针。
      //isReadonly && target[ReactiveFlags.IS_REACTIVE]:这儿查看两个条件:isReadonly 是否为真,以及 target 是否具有 ReactiveFlags.IS_REACTIVE 标志。isReadonly 表明当前的操作是试图创立一个只读呼应式方针,而 ReactiveFlags.IS_REACTIVE 查看 target 是否已经是一个呼应式方针。
      //该代码本质上还是优化Vue的功能
      
    • 持续

       // target already has corresponding Proxy
      const existingProxy = proxyMap.get(target)
       if (existingProxy) {
        return existingProxy
        }
      //这段代码中的proxyMap指的是Vue中已经创立和缓存的方针
      //在Vue中运用的是weakMap这种方针,这种方针能够使Obj作为key,而且废物收集器会自动收回这个指代的方针
      //换句话说,假如没有其他引证指向这个键方针,它会被废物收回掉,其对应的值(呼应式署理)也会随之消失。
      
       // only specific value types can be observed.
      //只有特定类型的值能够被监听
       const targetType = getTargetType(target)
       if (targetType === TargetType.INVALID) {
        return target
        }
      ​
      ​
      //下面是获取方针的类型办法
      function getTargetType(value: Target) {
       return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
        ? TargetType.INVALID
         : targetTypeMap(toRawType(value))
      }
      //value[ReactiveFlags.SKIP] || !Object.isExtensible(value):value[ReactiveFlags.SKIP]:这部分查看方针方针 value 是否具有 ReactiveFlags.SKIP 标志。在 Vue 3 中,假如一个方针的 __v_skip 特点(对应 ReactiveFlags.SKIP)被设置为 true,则该方针不会被转化为呼应式方针。这常用于越过不需求呼应式处理的内部方针或第三方库方针。
      //!Object.isExtensible(value):这个查看运用 Object.isExtensible() 办法来判别方针方针 value 是否是可扩展的(即能否增加新的特点)。假如一个方针不是可扩展的,那么它也不适合转化成呼应式方针,因为呼应式体系需求能够增加呼应式处理所需的内部特点。
      //假如以上一个为真,就直接回来INVALID,不适合转化//运用了Vue中的一个内置的办法,该办法通经过获取转为String的类型,获取准确的办法
      export const toRawType = (value: unknown): string => {
       // extract "RawType" from strings like "[object RawType]"
       return toTypeString(value).slice(8, -1)
      }
      ​
      //再运用targetTypeMap办法
      function targetTypeMap(rawType: string) {
       switch (rawType) {
        case 'Object':
        case 'Array':
         return TargetType.COMMON
        case 'Map':
        case 'Set':
        case 'WeakMap':
        case 'WeakSet':
         return TargetType.COLLECTION
        default:
         return TargetType.INVALID
        }
      }
      //获取对应的类型0,1,2
      
      //创立署理方针
      const proxy = new Proxy(
        target,
        targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers,
        )
      //Proxy有两个参数,第一个为署理方针,第二个为当办法变化处理的办法
      //这儿的第二个参数表示是否为特别类型collectionHandlers || baseHandlers
       proxyMap.set(target, proxy)
      //在weakMap缓存中存入该方针key:value
       return proxy
      ​
      

2.isReactive

Checks if an object is a proxy created by ,查看是否为Proxy创立

export function isReactive(value: unknown): boolean {
 if (isReadonly(value)) {
  return isReactive((value as Target)[ReactiveFlags.RAW])
  }
 return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}
//查看方针,假如是isReadonly,就会去尝试读取源方针eactiveFlags.RAW
//假如为不是只读,读取ReactiveFlags.IS_REACTIVE 标志
//!!回来结果

3.isReadonly,isShallow, isProxy

都是相似的操作,经过读取原始方针中的isXXX来确定是否为对应的类型

4. toRaw

回来Vue创立的署理的原始方针

export function toRaw<T>(observed: T): T {
 const raw = observed && (observed as Target)[ReactiveFlags.RAW]
 return raw ? toRaw(raw) : observed
}
​
//这儿的RAW是Vue中的ReactiveFlags中的一个,表示原始方针
//递归解包,获取最底层的数据

5.MarkRaw

该办法会符号方针,使其不会转化为署理,回来方针自身。

export function markRaw<T extends object>(value: T): Raw<T> {
 //查看方针是否可拓宽,只有可拓宽的函数才能够修正
 if (Object.isExtensible(value)) {
  def(value, ReactiveFlags.SKIP, true)
  }
 return value
}
//该办法会符号方针,假如该方针式可继承的,经过def函数,修正函数的方针
export const def = (obj: object, key: string | symbol, value: any) => {
 Object.defineProperty(obj, key, {
  configurable: true,
  enumerable: false,
  value,
  })
}
//给该函数符号越过
//主要用于第三方库和内部体系简化处理

6.toReactive

export const toReactive = <T extends unknown>(value: T): T =>
  //判别是否为方针,假如是直接进行toReactive处理,假如不是直接回来原始数据
 isObject(value) ? reactive(value) : value
// return createReactiveObject(
//   target,
//  false,
//  mutableHandlers,
//  mutableCollectionHandlers,
//  reactiveMap,
//)

7.toReadonly

回来一个只读的proxy方针,相同调用toReactive处理,可是传入参数不同

export const toReadonly = <T extends unknown>(value: T): DeepReadonly<T> =>
 isObject(value) ? readonly(value) : (value as DeepReadonly<T>)
​
//return createReactiveObject(
//  target,
//  true,
//  readonlyHandlers,
//  readonlyCollectionHandlers,
//  readonlyMap,
//)