Vue源码概述
Vue源码概述
Vue 2.x 的源码就是利用了 Flow 做静态类型检查。
timerFunc
Vue 在构建时,会初始化一个 timerFunc 函数,该函数会把 flushCallbacks 函数放入异步队列中。
flushCallbacks 函数负责清空在 Vue.nextTick 中定义的批量异步操作。
nextTick 负责收集包装异步函数,添加到 callbacks 数组中,并且触发 timerFunc 函数。
nextTick 就是把一个异步函数加入队列中,等同步方法执行完了立刻执行。
Vue
Vue 函数接收一个 options 参数,执行 _init() 函数。
1 | function Vue (options) { |
初始化流程
1 | mergeOptions() |
创建之前的初始化
合并options
生命周期,绑定父组件和根组件
绑定自定义事件:因为在初始化数据时可能触发
初始化插槽:因为在插槽中的可能用到响应式数据
响应式数据的初始化
beforeCreate 和 created 之间主要是处理响应式数据和方法,流程
初始化 inject
绑定函数到组件
初始化 data
初始化 computed
初始化 watch
初始化 provide
实例挂载
1 | function mountComponent(){ |
updateComponent 的调用会执行 vm._update 和 vm._render
Watcher 在这里主要是初始化和数据变化时,执行回调函数。
把模版编译成render函数
1 | const ast = parse(template.trim(), options) |
解析字符串,生成树:涉及正则表达式,借鉴 simplehtmlparser.js,生成对象树
优化
生成render代码
响应式数据
Observer 类会被附加到被观察的对象上,也就是说,每一个响应式对象上都会有一个 __ob__;然后对数据类型进行了一个判断;若是数组,则判断是否存在 __proto__ 属性,因为要通过原型链覆盖数组的几个方法,
defineReactive 的作用就是利用 Object.defineProperty 对数据的读写进行劫持,给属性 key 添加 getter 和 setter ,用于依赖收集和通知更新。如果传进来的值依旧是一个对象,则递归调用 observe 方法,保证子属性都能变成响应式。
一个 key 一个 dep,在 key 被调用时,dep 收集依赖,在 key 被重新赋值时,dep 通知所有的依赖更新。
Dep 收集 Watcher,通知 Watcher 更新。
一个组件可以有多个 Watcher(组件至少一个,还有计算属性)
Watcher 与一个组件绑定,通知 Watcher 就是让组件重新渲染。
创建 Watcher 对象的情况:
创建组件时
创建计算属性时
手动调用
$watcher
watcher 更新
如果是渲染 watcher 则执行 this.cb.call(this.vm, value, oldValue)。渲染 Wather 的实例化是在挂载时 mountComponent 方法中执行的:实际就是实例化时传入的第二个参数 updateComponent 。
渲染
Vue 1.x Watcher 时DOM元素级别,数据变化时可以精确到特定元素。
Vue 2.x 开始Watcher改为组件级,数据变化时通知组件更新,组件自己再通过diff算法确定更新具体的哪些元素。
vm._render()
createElement
创建虚拟节点VNode
Vue 的 _update 是实例上的一个私有方法,主要的作用就是把 VNode 渲染成真实的 DOM。
内部会调用 patch 方法,精细化修改真实DOM
diff
对比算法,判断DOM节点是否可以复用。
最终会生成真实DOM并进行挂载。

