深入了解vue2没有在data中定义的属性非响应式的问题

关于vue2没有在data中定义的属性非响应式的问题

vue2 响应式的原理及实现

vue2 响应式数据 是通过 es5 中的 Object.defineProperty 方法来实现,把 data 定义的所有属性,转换为 get/set 方法,使用 Object.defineProperty 方法劫持

步骤:

  1. 遍历data中的所有属性转换为 get/set ,使用 Object.defineProperty 劫持
  2. 当data中定义的属性改变时 会触发 set 方法 通知 watcher 从而使它关联的组件重新渲染
    在这里插入图片描述





在这里插入图片描述
由此可见 图中定义了 data 对象 , 并且使用 Object.defineProperty 方法劫持了 data 对象中的 page 属性,在控制台分别输出了 data.page 和 data.name 的值
data.page 返回的值 后面还加上了 《后缀》 ,因为在 get 方法中 对字符串返回做了二次处理



回归正题 因为 vue 实例在加载 data 对象时 已经把 data 中的值 使用 Object.defineProperty 遍历过一遍, 当下次,直接使用 data[新属性] 这时 新属性是没有转化为 get/set使用 Object.defineProperty 劫持, 所以当这个新属性 的值 改变时,并不会触发视图变更,如下图
在这里插入图片描述
在控制台可见 course 对象是已经改变了的 但是 视图上却 没变更。

vue2 解决此类的部分

  1. 需要响应式的数据都在data中先声明
  2. 使用 this.$set 方法 Vue.set(object, propertyName, value)

如果data 中的一个对象 里面有很深的层级 ,并且有很多是前期不好声明的,而且我们一开始只能定义一个变量的名字 course ,那么接下来 全部使用 $set 方法来实现响应式 ,显然是比较繁琐的
解决办法 在 course 已经改变完成之后 里面那些没有前期定义的属性非响应式的 ,在最后把 course 重新生成一个新对象 再赋值给 course ,因为course最开始已经在data中定义了,当course改变会触发 defineProperty 方法,从而渲染视图
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Vue.js ,如果你在组件的 data 属性定义了一个属性,这个属性是不会被响应式的。只有在 data 定义属性才是响应式的。因此,如果你需要一个响应式属性,应该将其定义data 。 ### 回答2: 在data定义数据不是响应式的。 在Vue.js响应式系统是通过数据劫持来实现的。只有在组件的data选项定义数据才会被Vue.js监听并做出相应的更新。这意味着只有在Vue实例的data选项定义数据才是响应式的。 在data定义数据,如变量或常量,在Vue.js不会被自动地监听和更新。如果需要这些数据具有响应式的特性,可以通过使用Vue提供的Vue.set()或this.$set()方法来实现。这些方法可以用来将一个对象或数组转化为响应式的,并且可以对其属性或元素进行改变时触发更新。 例如,可以使用Vue.set()或this.$set()方法将一个变量定义Vue实例的属性,然后就可以在模板访问并自动触发更新。 总而言之,在Vue.js,只有在data选项定义数据响应式的,而在data定义数据需要手动转化为响应式来实现相应的更新。 ### 回答3: 在 Vue.js ,只有在 data 选项定义数据才是响应式的。当创建一个 Vue 实例时,Vue 会将 data 选项属性转换为 getter/setter,这样在修改属性值时,Vue 能够监听到属性值的变化并自动更新相关的视图。 而在 data定义数据是不具备响应式特性的。当在 Vue 实例的 methods、computed 或 watch 使用 data定义数据时,这些数据不会自动触发 reactivity(响应式)系统。如果需要让在 data定义数据具备响应式特性,可以使用 Vue 提供的 Vue.set 或 Vue.$set 方法来设置值,或直接通过改变对象属性的方式来达到响应式更新。 使用 Vue.set 或 Vue.$set 方法,我们可以将一个新的属性添加到对象,并且该属性具有响应式特性,即修改该属性会触发视图更新。示例如下: ```js // 在 data定义数据响应式data() { return { message: 'Hello Vue!', obj: { name: 'John', age: 30 } } }, // 在 methods 通过 Vue.set 或 Vue.$set 定义数据响应式的 methods: { updateData() { Vue.$set(this.obj, 'gender', 'male'); } } ``` 如果在 methods 方法直接通过改变对象属性的方式来添加属性,则该属性也会具有响应式特性,示例如下: ```js methods: { updateData() { this.obj.gender = 'male'; } } ``` 总结来说,只有在 data定义数据以及通过特定的方法或方式定义数据才具备响应式特性,而在 data定义的普通变量或对象则不具备响应式

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值