学习 vue2 源码 模板编译 流程:初始化数据 》 模板编译成 ast 语法树 》 变成 render() 》 生成虚拟 dom 》 变成真实 dom 》挂载到 el 模板编译 先找 render > template > el 里面的元素 数据劫持 通过 object.defineProperty 遍历,递归 实现数据劫持 数组通过重写数组原型方法实现数据劫持 生命周期 与 vue.mixin() 注入的全局属性合并 options:{data:[] , created:[]} 通过 callHook 在不同时机触发 收集依赖 dep 收集依赖 与 data 的属性一一对应 dep 与 watcher 是多对多 nextTick原理 当数据数据发生变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。 如果同一个 watcher 被多次触发,只会被推入到队列中一次。 然后,在下一个的事件循环“tick”中,Vue 执行队列里的所有回调。 watch原理 初始化遍历传入的watch对象,调用createWatcher创建Watcher watcher对象记录初始值,把自己添加到监听属性的dep上 当数据发生变化,依次触发watcher,用watcher上记录的旧值和新值调用watch对象传入的handler diff算法 用旧的虚拟dom和新的虚拟dom进行比对。 对比流程:前前——后后——交叉——暴力 添加多余的新vdom节点,删除多余的旧vdom节点 computed计算属性 通过 object.defineProperty 把computed的属性代理到vue实例 给每一个 computed 属性创建 watcher 通过lazy属性实现懒加载 通过dirty属性实现缓存 用栈的方式让 computed 的 watcher 和页面更新的 watcher 都与 data 属性里面的dep绑定