vue 运行浅析
利用浏览器版本分析 vue 的源码
vue 源码浅析
- 采用
new Vue(options)示例化一个 vue 对象- 利用
instanceOf检查是否采用 new 调用 this,避免非构造器模式使用 new
- 利用
- 内部调用
thi._init(options)实例化对象,该方法附着在 Vue 构造器的原型上- this._uid 标识
uid 的作用?
- this._isVue 标识
避免对 Vue 对象的观察
- 判断是否为组件
- 组件调用组件实例化
- 非组件合并传入配置项添加
$options属性,绑定了 Vue 内置的组件特性,核心特性包括$options.components原型上继承如下组件keepAliveTransitionTransitionGroup
$options.directives,原型继承如下指令model表单指令show显示指令
initProxy(vm)代理实例化的 vue 对象- 在实例上设置
has代理,检查自定义 vm 属性是否合法,包括如下几种- key 必须为字符串
- key 不存在与
vm.$data字段
- 在实例上设置
initLifecycle(vm)初始化 vm 的组件树结构initEvents(vm)初始化 vm 上绑定的时间监听组initRender(vm)- 绑定渲染函数
defineReactive$$1绑定响应式数据
callHook(vm,'beforeCreate')触发创建前钩子initInjections(vm)功能不清楚???initState(vm)检验 vm 相关属性- 检验属性
- 检验方法
- 检验data,并将
vm.$data上的属性代理到 vm 对象上,实现直接利用 vm.xx 访问$data上属性的功能 - 观察
observe(data)
initProvide解析 provide 属性callHook(vm, 'created');绑定观察者后触发created钩子- 若定义了
el触发挂载$mount方法
- this._uid 标识
数据跟新流程
读取流程
- 利用
this.xx读取组件 data 属性会触发proxyGetter陷阱函数,该陷阱函数会返回this._data[key]的结果 - 访问
this._data[key]触发reactiveGetter访问器返回该值
写入流程
- 利用
this.xx修改写入组件 data 属性时会触发proxySetter陷阱函数,该陷阱函数会设置this._data[key]的值 - 设定值会触发
reactiveSetter访问器属性,若检测到值得变化才会触发通知 - 值的变化会触发
dep.notify()的通知,通知会遍历dep.subs上的观察者,调用观察者的update()方法 - 进一步调用
queueWatcher将当前观察者推入,该步骤会清除对同于属性的多次修改 - 调用
nextTick(flushSchedulerQueue)处理被推入的更新队列注意该操作为异步,默认采用 Promise.resolve 触发
- 遍历执行队列中
watcher.run()方法 watcher.run()触发内部的 render 函数,更新视图