响应式与数据更新
在vue中,需要展示在页面上的数据必须在data中声明,没有在data中声明的属性将不会被vue感应。
vue会使用Object.defineProperty 方法 将data中的属性变成getter/setter型属性,每一个vue组件会对应一个watcher,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
虽然在初始化之后,不能去声明data中的属性(对于已经创建的实例,Vue 不允许动态添加根级别的响应式属),
但可以对嵌套对象中添加属性,在开发过程中,往往会遇到一个问题,即某个嵌套对象中增加或删除了某个属性,但页面表现上,对应元素没有生成或被删除。出现这个问题的原因在于vue无法检测到对象属性的添加和删除,如果要添加或删除属性,要生成新对象,替换这个老对象 ,示例:
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
vue对dom的更新是一个异步行为,如上述代码,并不是执行了这一句,someObject对应的dom中的值就会立即改变,如果在这句后面直接抓取dom取值,那么取得的还是旧值。 在实际开发中,如果混合使用了data数据更新,与dom抓取取值,很可能出现值不是最新的情况。
这个问题的根本原因就是vue对dom的更新是一个异步行为,dom并没有马上更新,实际上,vue在对数据更新时,会创建一个异步队列,一次性更新同一个事件循环中设置的所有数据,组件会在下一个事件循环更新(即异步队列中的数据会在下一个事件循环中更新)。vue提供了nextTick(),该方法接收一个回调函数,回调函数将在 DOM 更新完成后被调用,即可保证回调中抓取的dom值为最新值。