手摸手学习vue3源码二:reactive

91 阅读1分钟
  • 文件目录:packages/reactivity/src/reactive.ts
  • 关键函数:createReactiveObject
  • 地位:是vue3中的核心功能,该函数的核心内容就是给target设置proxy,为target添加get,set操作符。在触发get函数的时候,对依赖进行收集;在触发set函数的时候,执行所收集的依赖,从而达到数据更新,DOM视图更新(既数据响应式)
function createReactiveObject(
     target,
     isReadonly,
     baseHandlers,
     collectionHandlers,
     proxyMap
    ) {
     // target不是对象,直接返回;并且警告
     if (!isObject(target)) {
      return target
     }

     // target已经是个代理,直接返回
     if (target[ReactiveFlags.RAW] && !(isReadonly && target[ReactiveFlags.IS_REACTIVE])) {
      return target
     }
 
     // target已经是代理对象,返回
     const existingProxy = proxyMap.get(target)
     if (existingProxy) {
         return existingProxy
     }
 
     // 观察是否为特定类型
     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
      }
    }

    // 如果不是 Object,Array,Map,Set,WeakMap,WeakSet,直接返回target
    const targetType = getTargetType(target)
    if (targetType === TargetType.INVALID) {
     return target
    }

    // 上面情况都不存在,使用new Proxy定义响应式属性
    const proxy = new Proxy(target, targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers)
    proxyMap.set(target, proxy)
    return proxy

     // 如果target类型属于Map,Set,WeakMap,WeakSet,使用collectionHandlers,否则使用baseHandlers, 只处理Object,Array
 
}