一、概述
- 说明
- Vue内某个对象修改时,会对相关联的视图更新;vue会把在data选项中定义的实例使用Object.defineProperty将他们转为setter/getter,这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
- 每个组件都有个watcher实例,它监听着与组件相关联的property,一旦该property被更改(调用setter方法),watcher将会把这些相关组件重新渲染。
二.Vue不能检测数组和对象的变化
1.对象
-
具体表现
Vue 无法检测 property 的添加或移除。
由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。 -
解决方案
可以通过Vue.set()和Array.splice()修改原数组,即可触发状态更新。
2.数组
-
具体表现
Vue 不能检测以下数组的变动:- (1)当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
- (2)当你修改数组的长度时,例如:vm.items.length = newLength
-
解决方案
可以通过**arr.splice(newLength)**触发状态更新
三、声明响应式property
- 由于 Vue 不允许动态添加根级响应式 property,所以你必须在初始化实例前声明所有根级响应式 property,哪怕只是一个空值。data 对象就像组件状态的结构 (schema)。提前声明所有的响应式 property
四、$nextTick()
-
说明
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。 -
代码示例
Vue.component('example', { template: '<span>{{ message }}</span>', data: function () { return { message: '未更新' } }, methods: { updateMessage: function () { this.message = '已更新' console.log(this.$el.textContent) // => '未更新' this.$nextTick(function () { console.log(this.$el.textContent) // => '已更新' }) } } })
所以就要使用$nextTick(callback),回调函数在本次缓冲队列内事件处理完成后执行,此时数据是同步变化了的。