Proxy响应式核心是通过get/set拦截实现依赖收集与更新触发:读取时自动记录副作用函数为订阅者,写入时精准通知相关更新,并配合effect/trigger构建闭环,支持嵌套路径与数组边界处理。

用 Proxy 实现响应式 UI 绑定引擎,核心在于拦截对象属性的读取(get)和写入(set),在访问时收集依赖,在变更时触发更新。它不依赖编译时生成绑定类,也不需要手动调用 notify,而是靠运行时劫持自然形成响应式数据流。关键不是“做多少”,而是“在哪一刻建立联系”。
拦截读取:自动收集依赖
每次模板或组件中访问响应式对象的某个字段(如 state.count),Proxy 的 get 拦截器就会被触发。此时需做两件事:
- 记录当前正在执行的副作用函数(比如一个渲染函数或计算属性)为该属性的订阅者
- 把该属性路径(如
["count"])与副作用函数关联起来,存入依赖图(Dep Map)
例如:const state = reactive({ count: 0 }),当 {{ count }} 渲染时,就悄悄记下:“这个视图依赖 count”。后续只要 count 变了,就能精准通知它重跑。
拦截写入:精准触发更新
当代码执行 state.count = 5,Proxy 的 set 拦截器捕获该操作,立刻查找所有订阅了 count 的副作用函数,并逐个执行。
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
- 更新前可对比新旧值(避免无意义触发),例如用
Object.is(oldVal, newVal) - 若属性是对象,需递归调用
reactive处理其子属性,确保深层响应 - 数组索引赋值、
length修改等边界情况,需单独代理数组方法(如push、splice)
构建视图更新闭环:Effect + Trigger
不能只靠 Proxy 拦截,还需配套的响应式执行单元:
-
effect(fn):将传入的函数包装成响应式副作用,执行时激活依赖收集(进入“追踪模式”) -
trigger(target, key):在set中调用,根据 target 和 key 查找并执行所有已注册的副作用 - 每个副作用内部应有防重复执行机制(如加锁或队列去重),避免嵌套更新引发无限循环
这样,effect(() => app.innerHTML = state.message) 就成为一个可被自动调度的 UI 更新单元。
支持嵌套与动态路径:Key Path 解析与缓存
真实 UI 常访问嵌套结构(user.profile.avatar)或动态路径(list[i].name)。单纯用 Proxy 拦截顶层对象不够,需分层处理:
- 对每一层对象都创建 Proxy,形成响应式链;首次访问
user.profile时,返回已 reactive 化的子对象 - 对于数组索引访问(
arr[0]),拦截get并检查是否为数字键,是则触发arr的 “index” 依赖(类似 Vue 的__ob__.dep) - 高频访问路径可缓存解析结果(如
/user/profile/avatar→["user","profile","avatar"]),避免重复字符串分割










