在使用vuejs开发过程中,有时候出现修改对象属性后,视图并没有更新的问题。下面分析其产生原因并给出解决方法。
产生原因
Vue2使用双向数据绑定,当你把一个普通的 JavaScript 对象传入 Vue2 实例作为 data 选项,Vue2 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在属性被访问和修改时通知变更。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
因此,vue2 无法检测 property 的添加或移除。由于 Vue2 会在初始化实例时对 property 执行 getter/setter转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。对于已经创建的实例,Vue允许动态添加根级别的响应式 property。
解决方法
- Vue.set()
Vue.set(object,key,value)方法一次只能添加一个属性,例如:
1 | this.$set(this.message,'b',"我手一杯 品尝你的美"); |
- Object.assign或_.extend()
Object.assign或_.extend()可以往数据对象上添加多个属性,但是需要创建同时包含原属性、新属性的对象,从而有效触发watch()方法。例如:
1 | this.message = Object.assign({},this.message,{b:'我手一杯 品尝你的美',c:'留下唇印的嘴'}) |
参考链接
- vue修改对象属性,视图不更新this.$set和Vue.nextTick([callback,context]),by 青争小台.
- vue响应式数据-修改对象的属性值,视图不更新,by codeantenna.
- Vue3的响应式原理?一篇文章,八张图,三心为你解密~,by Sunshine_Lin.
- Vue3响应式原理解析,by liy1wen.