在vue中为什么你添加的属性,打印都有,视图却不更新?

在 Vue 中,如果在运行时动态给 data 添加新的属性,Vue 无法自动追踪这个新属性的变化。这是因为 Vue 使用的是 Object.defineProperty 进行数据劫持,而 Object.defineProperty 只能在对象初始化时对已有的属性进行监听,因此动态添加的属性不会被 Vue 侦测到,也不会触发视图的更新。

发生什么?

假设你在一个组件的 data 中没有定义 newProperty,然后你想动态添加它:

this.$data.newProperty = 'newValue';
console.log(this.newProperty); // 'newValue'

在上面的例子中,你虽然可以通过 $data 访问到 newProperty,但是 Vue 无法响应它的变化,界面也不会更新。

解决办法:

Vue 提供了两种方法解决这个问题:

  1. 使用 Vue.set() 方法:可以动态地将属性添加到响应式对象中,并确保它是响应式的。
Vue.set(this.someObject, 'newProperty', 'newValue');
  1. this.$set() 方法:与 Vue.set() 类似,适用于实例内的响应式数据。
this.$set(this.someObject, 'newProperty', 'newValue');

示例:

data() {
  return {
    person: {
      name: 'John'
    }
  };
},
mounted() {
  // 动态添加一个属性,Vue 无法追踪
  this.person.age = 25;
  
  // 正确的方式,Vue 会追踪到新属性的变化
  this.$set(this.person, 'age', 25);
}

Vue 源码分析:

在 Vue 源码中,Vue 初始化响应式数据时,会通过 initData() 函数遍历 data 对象上的属性,并调用 defineReactive() 方法。这个方法使用 Object.defineProperty 将属性定义为 getter 和 setter,从而使得 Vue 可以劫持数据的读取和更新。

然而,Object.defineProperty 不能对新增的属性进行监听。这就是为什么在运行时动态添加属性不会触发响应的原因。因此,Vue 提供了 set 方法,它使用 defineReactive 手动为新增属性设置响应式劫持。

场景:

动态给 data 添加属性常见于异步请求完成后,或者组件渲染过程中,需要给对象动态添加数据时。比如,一个用户表单可能开始时只有 nameemail 字段,但在某些交互下需要动态添加 phone 字段。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sherry Tian

打赏1元鼓励作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值