关于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 方法,从而渲染视图
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐