vue3通过proxy实现双向数据绑定,核心是利用get拦截收集依赖、set拦截触发更新,并结合dom事件将用户输入写回数据,形成数据与视图的双向同步通路。

Proxy 实现双向绑定的核心是拦截属性读写操作,在 set 时同步更新视图,在 get 时收集依赖,再配合 DOM 事件把用户输入反向写回数据——形成“数据→视图”和“视图→数据”两个通路。
拦截 get/set 构建响应式基础
Proxy 不修改原对象,而是创建一个代理层。关键在于 handler 中的 get 和 set:
-
get 拦截:当模板或代码读取属性(如
obj.msg)时触发,此时可记录当前正在执行的渲染逻辑(即“谁在用这个值”),为后续更新做准备 -
set 拦截:当赋值发生(如
obj.msg = 'new')时触发,除保存新值外,还要通知所有依赖该属性的视图部分重新渲染 - 必须返回
true表示操作成功,否则赋值会静默失败
绑定 input 实现视图到数据的回传
仅靠 set 拦截只能实现单向更新(数据变 → 视图变)。要完成“双向”,还需监听用户操作:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 给
<input>绑定input或change事件 - 事件回调中直接给代理对象赋值,例如
vm.msg = e.target.value - 这会触发 set 拦截,从而驱动其他关联视图(如
<p></p>标签)同步更新 - 注意避免更新循环:DOM 更新前应判断是否真有变化,比如
if (el.value !== value) el.value = value
处理嵌套与初始化细节
真实场景中,对象常有深层结构,且初始值需一次性同步到界面:
- Proxy 默认不递归代理嵌套对象,需在 get 返回对象时手动包装:
if (typeof value === 'object' && value !== null) return new Proxy(value, handler) - 页面加载时,得先将 data 的初始值填入对应 DOM 元素(如
input.value = vm.msg),否则首次渲染为空 - 数组方法(push/pop)不会触发 set,需在 handler 中重写或劫持其原型方法,或改用
Reflect.set配合检测
对比 defineProperty 的优势与限制
Proxy 是 Vue 3 的响应式底层,相比 Object.defineProperty 更适合现代开发:
- 能监听属性新增、删除、in 操作、for...in 遍历等,defineProperty 完全无法捕获这些
- 天然支持 Map/Set/数组方法拦截,无需额外补丁
- 不兼容 IE,若需支持旧浏览器,仍需 fallback 到 defineProperty 方案
- Proxy 实例不能被
JSON.stringify正常序列化,调试时建议用Reflect.getPrototypeOf(proxy)查看原始数据
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










