首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Vue3的Proxy解决了多少Vue2中defineProperty解决不了的问题?

Vue3的Proxy解决了多少Vue2中defineProperty解决不了的问题?

作者头像
watermelo37
发布2025-06-13 11:44:02
发布2025-06-13 11:44:02
6700
代码可运行
举报
文章被收录于专栏:前端专精前端专精
运行总次数:0
代码可运行

一、Vue2 使用 defineProperty 的机制

在 Vue2 中,响应式系统是通过 Object.defineProperty 实现的,每个属性都通过 getter/setter 被拦截,从而实现依赖追踪和变更通知:

代码语言:javascript
代码运行次数:0
运行
复制
Object.defineProperty(obj, 'key', {
  get() {
    // 收集依赖
    return value;
  },
  set(newVal) {
    // 通知更新
    value = newVal;
  }
});

但defineProperty 有天然的缺陷:

问题

说明

1. 无法监听新增属性

给对象新增的属性不会自动响应,需要 Vue.set。

2. 无法监听删除属性

删除属性也不会触发更新,需要手动触发。

3. 无法直接监听数组索引变化

修改数组索引无法被侦测,需要使用特定方法(如 Vue.set)。

4. 无法拦截整个对象

只能一开始递归遍历每一个属性,无法整体拦截对象。

5. 性能问题(大量数据)

初始化时递归地遍历所有对象属性,成本很高。

为了弥补这些问题,会出现如Vue.set、Vue.delete这些方法来实现对新增和删除属性的监听,没办法,defineProperty从底层上就有这些限制,尤雨溪本人来也解决不了。

二、Proxy 解决了哪些 Vue2 时代的问题?

来,咱们一一对应看。

1、新增属性能自动响应

Vue2问题:

代码语言:javascript
代码运行次数:0
运行
复制
vm.obj.a = 123;  // 不会响应式更新,必须 Vue.set(vm.obj, 'a', 123);

Vue3解决:

代码语言:javascript
代码运行次数:0
运行
复制
reactiveObj.a = 123; // 自动响应,无需手动 set!

因为 Proxy 能拦截 set 操作,即使属性原本不存在,也能监听到。

2、删除属性也能触发响应

Vue2问题:

代码语言:javascript
代码运行次数:0
运行
复制
delete vm.obj.a; // 删除了但不会通知视图更新

Vue3解决:

代码语言:javascript
代码运行次数:0
运行
复制
delete reactiveObj.a; // 自动触发响应,页面同步更新!

因为 Proxy 支持拦截 deleteProperty 操作,天然监听删除。

3、数组索引可以被正确追踪

Vue2问题:

代码语言:javascript
代码运行次数:0
运行
复制
vm.arr[2] = 10; // 不会响应,需要用 Vue.set(vm.arr, 2, 10)

Vue3解决:

代码语言:javascript
代码运行次数:0
运行
复制
reactiveArr[2] = 10; // 自动触发响应,刷新视图!

因为 Proxy 能拦截数组下标访问和修改,索引不再是问题。

4、不再需要递归遍历属性

Vue2问题:

初始化时,需要递归 walk 整棵数据树,开销大,尤其是深层嵌套对象或大数组时,性能堪忧。

Vue3解决:

只要一层 Proxy,就可以懒代理,当访问到某个子对象时,再进行子对象的代理(懒代理 Lazy Proxy)。

5、更好支持 Map、Set、WeakMap

Vue2问题:

  • defineProperty 只能拦截对象的属性,无法拦截 Map、Set 的操作。
  • Vue2基本放弃了对这些复杂结构的响应式支持。

Vue3解决:

  • Proxy 可以拦截.get()、.set()、.add()、.delete()等各种方法。
  • 因此,Vue3 内置了对 Map、Set 的响应式支持!
代码语言:javascript
代码运行次数:0
运行
复制
import { reactive } from 'vue';

const map = reactive(new Map());
map.set('key', 'value'); // 响应式

三、结语

可以说,Proxy 是 Vue3 响应式革命的基石。Vue3 用 Proxy,完美解决了 Vue2 中 defineProperty 无法监听“新增属性、删除属性、数组索引、复杂数据结构”等一系列痛点,同时带来了更高效、更优雅、更强大的响应式体验。

只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Vue2 使用 defineProperty 的机制
  • 二、Proxy 解决了哪些 Vue2 时代的问题?
    • 1、新增属性能自动响应
    • 2、删除属性也能触发响应
    • 3、数组索引可以被正确追踪
    • 4、不再需要递归遍历属性
    • 5、更好支持 Map、Set、WeakMap
  • 三、结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档