前端/移动开发面试题更新 2026-08-05

在 Vue 中,如果在一个已经创建的对象上动态添加新的属性,会有什么后果?有哪些有效的解决办法?

前端/移动开发技术原理问题排查Vue

考察说明

考察对 Vue 响应式原理的理解,特别是对象属性劫持的机制,以及处理动态添加属性的能力。

回答思路

  1. 【回答框架 1】Vue 2 使用 Object.defineProperty 对 data 中的对象进行递归劫持,在初始化实例时,只有已经存在的属性会被转换为 getter/setter,从而成为响应式属性。若是给响应式对象直接新增属性,该属性并未经过 defineProperty 处理,因此不会触发视图更新。解决办法之一是使用 Vue.set(object, propertyName, value) 或 this.$set,它们会调用 defineReactive 将新属性变为响应式,并触发依赖通知。
  2. 【回答框架 2】另一种方法是使用 Object.assign 或展开运算符创建一个新对象,将新属性合并进去,然后整体赋值给原对象的引用。例如 this.obj = { ...this.obj, newProp: value },这会触发该对象 setter,从而更新视图。Vue 3 采用 Proxy 实现响应式,可以拦截属性的新增和删除,因此直接添加属性会自动成为响应式,无需特殊处理。
  3. 【回答框架 3】在 Vue 2 中,还可以提前在 data 中声明所有可能用到的属性,包括初始值为 undefined 或 null,这样在初始化时就会被劫持,后续修改即为响应式。这是最保险的方式,但可能不够灵活。
  4. 【关键点 1】Vue 2 响应式基于 Object.defineProperty,只能劫持已存在的属性。
  5. 【关键点 2】直接新增属性无法触发视图更新,需要使用 Vue.set 或 this.$set。
  6. 【关键点 3】可以使用 Object.assign 或展开运算符重新赋值对象,实现响应式更新。
  7. 【关键点 4】Vue 3 基于 Proxy,可以自动拦截新增属性,无需额外处理。
  8. 【易错点 1】误以为直接添加属性也能更新视图,导致修改不生效却找不到原因。
  9. 【易错点 2】使用 Vue.set 时,若对象是响应式的根数据,需确保对象存在,否则需先赋值。
  10. 【易错点 3】在 Vue 2 中,使用数组索引设置元素或修改 length 也不会触发更新,需使用 splice 或 Vue.set。