vue响应式数据能自动更新视图,因其通过proxy/object.defineproperty劫持读写并建立依赖关系;原生js对象无此机制,修改后需手动更新dom。

Vue 的响应式数据不是普通对象,它背后有一套追踪依赖、触发更新的机制;而原生 JavaScript 对象默认没有任何自动更新视图的能力。关键区别不在“长得像不像”,而在“变了之后会不会通知界面”。
响应式能力:改了就自动更新视图
Vue 中用 ref() 或 reactive() 创建的数据是响应式的。只要你在模板中用了它,或者在计算属性、侦听器里读取了它,Vue 就会记住这个关系。一旦值变了,关联的 DOM 就自动重绘。
原生 JS 对象没有这层能力。比如:
const obj = { count: 0 };
// 改了 obj.count,页面不会动,哪怕你把它绑在 innerHTML 里
要让它生效,你得手动写更新逻辑——查 DOM、赋值、处理事件……整个链条都得自己搭。
数组操作:哪些方法真正“有效”
Vue 的响应式系统只拦截了部分数组方法。能触发更新的有:
- push() / pop() / shift() / unshift()
- splice() / sort() / reverse()
- Vue.set() 或 Vue.$set()(Vue 2) / Vue.set(arr, index, val)(Vue 3 中推荐用 proxy + ref)
这些方法直接修改原数组,Vue 能捕获到变化。
但下面这些原生方法不会触发更新,因为它们不改原数组,只返回新数组:
- filter() / map() / concat() / slice()
- 直接通过索引赋值:arr[0] = 'new'(Vue 3 中 Proxy 可部分支持,但 Vue 2 完全不响应)
所以别写 list = list.filter(...),而应写 list.splice(0, list.length, ...list.filter(...)) 或用 ref 重新赋值。
数据劫持方式:Proxy vs 普通属性访问
Vue 3 使用 Proxy 包裹对象,能监听任意属性的读写,包括新增或删除属性、遍历操作(如 in、Object.keys)。
原生 JS 对象的属性访问是“裸奔”的,读写都不留痕迹。你没法知道谁读了 obj.name,也没法在 obj.age = 18 发生时自动做点别的事。
Vue 2 用 Object.defineProperty 实现响应式,但它不能检测新增/删除属性,也不能监听数组索引赋值——这也是 Vue 3 升级 Proxy 的核心原因。
依赖收集:谁用谁注册,变了就通知
Vue 响应式不是“轮询”或“脏检查”,而是靠精确的依赖关系网:
- 组件渲染时,读取响应式数据会触发 getter,此时 Vue 记下“当前正在执行的函数(渲染函数)”是这个数据的订阅者
- 数据变更时,setter 触发,Vue 找出所有订阅者,通知它们重新运行
原生 JS 没有这种机制。你改一个变量,没人知道,也没人关心——除非你自己加发布订阅、用 Proxy 手动实现,否则就是静默的。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











