vue响应式对象解析

23 阅读2分钟

image.png

流程

api->响应式包装类->响应式对象

创建条件

  1. isObject
  2. Object.isExtensible Object.seal/Object.freeze 冻结对象 defineProperty proxy
  3. target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"]) 不是原始值和只读响应式对象

差异

1.不同
raw reactive(raw+shallow+readonly) ref
raw reactive rawReactive shallowReactive readonlyReactive
ref 类似
xx 属性化响应式对象

isXX 判断
toXX 转化
__V_isXX 唯一标识
xxHandler 代理行为 依赖追踪
xxCollectionHandler 集合
xxMap 缓存处理

raw 对象

  1. object array
  2. map set weakMap weakSet
  3. 非法对象

基础属性需要ref包装

reactive proxy对象
属性__v_raw __v_isReactive __v_isShallow __v_isReadonly

优化

const reactiveMap = /* @__PURE__ */ new WeakMap();
const shallowReactiveMap = /* @__PURE__ */ new WeakMap();
const readonlyMap = /* @__PURE__ */ new WeakMap();
const shallowReadonlyMap = /* @__PURE__ */ new WeakMap();

代理缓存

关系

image.png

以下AI给出

  • reactive:深度可变的响应式 Proxy(嵌套对象也会被递归转为响应式)。
  • readonly:深度只读的响应式 Proxy(禁止写入,嵌套也只读)。
  • shallowReactive:浅层可变(仅对象第一层为响应式,嵌套不递归)。
  • shallowReadonly:浅层只读(仅第一层只读,嵌套不递归)。
  • ref:用一个带有 value 的容器包装任意值,读写通过 .value 触发依赖;shallowRef 只在根层处理,不深度转换内部对象。
  • raw:原始对象(非代理);可通过 toRaw(proxy) 取回,或用 markRaw(obj) 标记跳过响应式。
  • proxy(泛指):由 Proxy 生成的代理对象,包含 reactive/readonly 的各种变体;isProxy 用于判断是否任一响应式或只读代理。

  • v_isReactive:标识“是否为可变的响应式代理”(readonly 也会有代理,但它返回 false)。

  • v_isReadonly:标识“是否为只读代理”。
  • v_isShallow:标识“是否为浅层(shallow)模式”(适用于 shallowReactive / shallowReadonly,ref 也会带有同名标志)。
  • v_raw:从代理上可取到“原始目标对象”的入口(配合内部校验使用,外部建议用 toRaw)。
  • v_skip:标记“不要把这个对象做成响应式”(markRaw 会设置它;VNode 也带这个标记)。
  • 备注:没有 __v_isRaw,你看到的是 __v_raw。