# vue 中 this.$set

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property

# 出现的问题

两种情况下修改数据 Vue 是不会触发视图更新的

  • 当我们给响应式的对象新增属性时,新增的属性并不会显示到页面中;这是由于对象及其属性在 vue 初始化时已处理成响应式的,即当我们改变对象的值或属性的值时,会触发其在页面上的更新,但是当页面加载完成后,新增的属性 b 和 c 就不是响应式的,虽然能在对象中新增属性,但新增的属性并不是响应式的,也就无法体现在页面上。
  • 同样的对于响应式的数组,增加元素、修改数组长度时,数组的这些变化也不会反映到页面中。数组本身是发生变化了,但是没有及时体现在页面上。

# 如何解决上述问题

通常使用 vue 中的this.$set()来解决

this.$set(target, propertyName/index, value)时,target 为需要添加属性的对象/数组,propertyName 是要添加的属性名|index 是数组下标,value 为属性 propertyName/index 对应的值。

# 原理

因为响应式数据 我们给对象和数组本身都增加了__ob__属性,代表的是 Observer 实例。当给对象新增不存在的属性 首先会把新的属性进行响应式跟踪 然后会触发对象__ob__dep 收集到的 watcher 去更新,当修改数组索引时我们调用数组本身的 splice 方法去更新数组

defineReactive(ob.value, key, val);
ob.dep.notify();
Last Updated: 3/5/2022, 2:50:47 PM