MST

星途 面试题库

面试题:Vue响应式系统中如何处理对象新增属性的响应式

在Vue开发中,当在已创建的响应式对象上新增属性时,默认情况下Vue的响应式系统不会自动追踪该属性的变化。请说明怎样让新增属性也具备响应式,解释原理以及相关的API使用场景和限制。
32.9万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

让新增属性具备响应式的方法

  1. 使用 Vue.set (Vue 2.x) 或 this.$set (在组件实例中)
    • 示例
    import Vue from 'vue';
    const vm = new Vue({
      data: {
        obj: {
          name: 'John'
        }
      }
    });
    Vue.set(vm.obj, 'age', 30);
    
    • 在组件中使用
    export default {
      data() {
        return {
          obj: {
            name: 'John'
          }
        };
      },
      mounted() {
        this.$set(this.obj, 'age', 30);
      }
    };
    
  2. 使用 Object.assign 创建新对象 (Vue 2.x)
    • 示例
    import Vue from 'vue';
    const vm = new Vue({
      data: {
        obj: {
          name: 'John'
        }
      }
    });
    vm.obj = Object.assign({}, vm.obj, { age: 30 });
    
  3. 在Vue 3.x中使用 reactiveref
    • 使用 reactive
    import { reactive } from 'vue';
    const state = reactive({
      obj: {
        name: 'John'
      }
    });
    // 新增响应式属性
    state.obj.age = 30;
    
    • 使用 ref
    import { ref } from 'vue';
    const objRef = ref({
      name: 'John'
    });
    // 新增响应式属性
    objRef.value.age = 30;
    

原理

  1. Vue 2.x:Vue在初始化数据时,会通过 Object.defineProperty 方法将数据的属性转换为 gettersetter,从而实现数据劫持和响应式追踪。当新增属性时,默认不会进行这种转换,所以不会具备响应式。Vue.set 方法会对新添加的属性进行 Object.defineProperty 转换,使其具备响应式。Object.assign 方法是通过创建一个新对象,重新对新对象的所有属性进行响应式转换,从而使得新属性也具备响应式。
  2. Vue 3.x:Vue 3.x 使用 Proxy 来实现响应式系统。Proxy 可以直接监听对象的操作,包括新增属性,所以在 reactive 创建的响应式对象上新增属性会自动具备响应式。而 ref 本质上也是基于 reactive 实现的,通过 .value 访问内部值,对其进行操作也能实现响应式。

相关API使用场景和限制

  1. Vue.set / this.$set (Vue 2.x)
    • 使用场景:适用于在已有的响应式对象上动态添加属性,并且希望该属性能够被Vue的响应式系统追踪的场景,例如在组件中动态给对象添加新字段。
    • 限制
      • 必须传入目标对象、属性名和属性值三个参数,使用相对固定。
      • 如果目标对象是一个数组,不能使用它来直接修改数组的长度,应使用数组的变异方法(如 pushpop 等)。
  2. Object.assign (Vue 2.x)
    • 使用场景:适用于需要一次性添加多个属性到响应式对象,并且需要让这些新属性都具备响应式的场景。
    • 限制
      • 创建新对象会产生额外的性能开销,尤其是对象较大时。
      • 会丢失原对象的原型链,因为 Object.assign 创建的是一个全新的普通对象。
  3. reactiveref (Vue 3.x)
    • 使用场景reactive 适用于创建复杂的响应式对象,ref 适用于创建基础类型或对象的响应式引用,在Vue 3项目开发中广泛使用。
    • 限制
      • reactive 创建的对象是深度响应式的,但对一些原生数据结构(如 MapSet)的响应式支持有一定的局限性,需要手动处理某些操作。
      • ref 在模板中使用时,对于对象类型,需要通过 .value 访问,在某些场景下可能略显繁琐。