Vue3.0源码解析「reactive」篇 — 1.包概述以及全局变量

包概述

reactive 这个包在 vue 内部被嵌入到vue的渲染器中(@vue/runtime-dom),也可以单独抽离使用。

下方为整个reactive的文件结构,忽略掉 _tests_ 测试文件和一些配置以及说明文件,有意义的代码都在 srcindex.js 里面:

.
├── __tests__  // 单元测试目录
├── index.js
└── src
    ├── index.ts
    ├── baseHandlers.ts 	// 基本类型的处理器
    ├── collectionHandlers.ts  	// Set Map WeakSet WeckMap的处理器
    ├── computed.ts 		// computed API
    ├── effect.ts 		// effect\trigger\track的具体实现
    ├── operations.ts 		// trigger\track的类型定义
    ├── reactive.ts 		// reactives API
    └── ref.ts 			// ref API 
复制代码

Consistents

Target

Target 定义一个响应式代理对象类型(包含所有类型标识属性可选签名):

 export interface Target {
   [ReactiveFlags.SKIP]?: boolean
   [ReactiveFlags.IS_REACTIVE]?: boolean
   [ReactiveFlags.IS_READONLY]?: boolean
   [ReactiveFlags.RAW]?: any
 }
复制代码

ReactiveFlags

ReactiveFlags 用于标注响应式代理的类型:

  • IS_REACTIVEIS_READONLY 比较容易理解就是响应式代理类型和只读响应式代理类型。
  • SKIP比较特殊,在markRaw中用于标注禁止响应式代理。
  • RAWraw 有半成品的意思,是一个指向被代理对象的指针。
 export const enum ReactiveFlags {
   IS_REACTIVE = '__v_isReactive',
   IS_READONLY = '__v_isReadonly',
   SKIP = '__v_skip',
   RAW = '__v_raw'
 }
复制代码

TargetType

用于标识被代理对象应该被走的处理策略:

 const enum TargetType {
   INVALID = 0,
   COMMON = 1,
   COLLECTION = 2
 }
复制代码

getTargetType

如果要被代理的对象有 SKIP 标识或者被设置为进制扩展对象,那么 TargetType 就是 INVALID 无法添加代理,不然则判断 对象的类型:

  • Object|Array:这两个的基础类型都是 object,就是普通可代理对象 — COMMON
  • Map|Set|WeakSet|WeakMap:这四个属于特殊集合类型,需要添加额外的操作来添加代理 — COLLECTION
  • other like primitive:其他的类型都是非法类型 — INVALID
 function getTargetType(value: Target) {
   return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
     ? TargetType.INVALID
     : targetTypeMap(toRawType(value))
 }
 ​
 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
   }
 }
复制代码

TargetMaps

这个 weakMap 储存的是 targetproxy 的映射,而不是 targetdepMap 的映射:

 export const reactiveMap = new WeakMap<Target, any>()
 export const shallowReactiveMap = new WeakMap<Target, any>()
 export const readonlyMap = new WeakMap<Target, any>()
 export const shallowReadonlyMap = new WeakMap<Target, any>()
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享