Vue 给对象添加新属性时视图不更新


vue2.x 的响应式

  • 实现原理:

    • 对象类型:通过 Object.defineProperty() 对属性的读取、修改进行拦截(数据劫持)。

    • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

      1
      2
      3
      4
      Object.defineProperty(data, "count", {
      get() {},
      set() {},
      });
  • 存在问题:

    • 新增属性、删除属性, 界面不会更新。
    • 直接通过下标修改数组, 界面不会自动更新。

Vue3.0 的响应式

解决办法

在 Vue 2 中,当你向一个对象添加新属性时,Vue 不会自动触发视图的更新,因为 Vue 只会追踪已经存在于数据对象中的属性。如果你需要在视图中响应新属性的变化,你可以使用 Vue 的 $set 方法或 JavaScript 的 Object.assign 来更新对象,从而触发视图的刷新。

  1. 使用 Vue 的 $set 方法

    1
    2
    // 假设你有一个名为 object 的数据对象
    this.$set(object, "newProperty", "new value");

    上面的代码将在 object 对象上添加一个新属性 newProperty,并设置其值为 'new value',同时会触发视图的更新。

  2. **使用 JavaScript 的 Object.assign**:

    1
    2
    // 假设你有一个名为 object 的数据对象
    object = Object.assign({}, object, { newProperty: "new value" });

    这将创建一个新对象,包含 object 中的所有属性以及新属性 newProperty,然后将新对象分配给 object,这也会触发视图的更新。

  3. $forceUpdate

    请注意,$forceUpdate 应该谨慎使用,因为它会绕过 Vue 的响应式系统,可能会导致性能问题和难以维护的代码。在大多数情况下,应该遵循 Vue 的响应式数据规则,让 Vue 自动处理视图的更新。

无论哪种方法,都可以让 Vue 检测到对象属性的变化并更新视图。确保在操作对象属性之前,你需要确保 Vue 已经响应式地跟踪了该对象,或者使用上述方法来添加新属性。

Reference

Object.defineProperty()