理解vue2的原理,以及修改数据页面不更新的原理和解决方案
vue2双向数据绑定原理
vue2的双向数据绑定(又称响应式)原理,是通过数据劫持结合发布订阅模式的方式来实现的,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。
官网上写追踪数据变化原理
- 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property ,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。
- 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在data中的 property 被访问和修改时通知变更。
- 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
检测变化的注意事项
- Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
比如:
var vm = new Vue({data:{formData:{acNo: "89111"},list: []}
})// `vm.formData.acNo` 是响应式的(当acNo变化的时候,视图有用到acNo的地方会自动更新)
vm.formData.acName = "小小"
// `vm.formData.acName` 是非响应式的(当a变化的时候,视图有用到b的地方不会自动更新)
- 对于已经创建的实例对象,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。
Vue.set(vm.formData,'acName ',"小小")
//或者
this.$set(this.formData,'acName',"小小")
-
数组
Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
// Vue.set
this.$set(this.list, 2, "新值")
// Array.prototype.splice
this.list.splice(2, 1, "新值")