Vue 是一种非侵入式的响应式框架。数据模型仅是普通 js 对象,当你修改他们,视图会自动更新。
如何追踪 Dom 变化
- 当把普通的 js 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象的所有属性,并使用 Object.defineProperty() 把这些属性全部转换为 getter 和 setter;
- 这些 getter 和 setter 用户无感知,Vue 利用他们跟踪依赖,在属性被访问和修改时通知变更。
- 每一个 Vue 都对应一个 watcher 实例,会在第一次组件渲染的过程中把“数据属性”(也就是 data 对象)记录为依赖,当 setter 触发时,通知 watcher 触发其关联的组件重新渲染;

声明响应式 data 属性
-
Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明所有根级响应式属性,哪怕只是一个空值
var vm = new Vue({ data: { // 声明 message 为一个空值字符串 message: '' }, template: '<div></div>' }) // 之后设置 `message` vm.message = 'Hello!' -
data 对象就像组件状态的结构 (schema)。提前声明所有的响应式属性,可以让组件代码在未来修改或给其他开发人员阅读时更易于理解
异步更新队列
- Vue 更新 Dom 是异步的;
- 侦听到数据变化,Vue 开启一个队列,缓冲在同一个事件循环中发生变更的所有数据;
- 若一个 watcher 被多次触发,只会被推入队列一次(这样可以去除重复数据对于避免不必要的计算和 DOM 操作)
- Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替
-
如何基于更新后的 Dom 做些操作?
Vue.component('example', { template: '<span></span>', data: function () { return { message: '未更新' } }, methods: { updateMessage: function () { this.message = '已更新' console.log(this.$el.textContent) // => '未更新' this.$nextTick(function () { console.log(this.$el.textContent) // => '已更新' }) } } })-
$nextTick() 返回一个 Promise 对象,所以你可以使用新的 ES2017 async/await 语法完成相同的事情:
methods: { updateMessage: async function () { this.message = '已更新' console.log(this.$el.textContent) // => '未更新' await this.$nextTick() console.log(this.$el.textContent) // => '已更新' } }
-