写在前面
上一篇文章 《一口气看完Vue源码》 中对大体流程做了个分析,但由于过程太过冗长导致文件零散,所以可能还不了解 Vue构造函数 中的某些值是哪儿来的。这一章节主要讲的是 Vue构造函数 的创建,会从生成到添加属性完毕的顺序依次介绍每个文件中对 Vue构造函数 的操作。
core/instance/index.js
- 创建 Vue 的构造函数
Vue = {}
core/instance/init.js
- 给 Vue 的原型上添加 _init 方法
Vue = {
prototype: {
/* new add start */
_init() {}
/* new add end */
}
}
core/instance/state.js
- 给 Vue 的原型上添加 $data ( 获取 options._data )
- 给 Vue 的原型上添加 $props ( 获取 options._props )
- 给 Vue 的原型上添加 $set 方法 ( 解决对象和数组在设置新内容时无法触发依赖的问题 )
- 给 Vue 的原型上添加 $del 方法 ( 解决对象在删除时无法触发依赖的问题 )
- 给 Vue 的原型上添加 $watch 方法
Vue = {
prototype: {
_init() {},
/* new add start */
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
/* new add end */
}
}
core/instance/events.js
- 给 Vue 的原型上添加 $on 方法 ( 发布订阅 - 订阅事件 )
- 给 Vue 的原型上添加 $once 方法 ( 发布订阅 - 订阅一次性事件 )
- 给 Vue 的原型上添加 $off 方法 ( 发布订阅 - 取消事件 )
- 给 Vue 的原型上添加 $emit 方法 ( 发布订阅 - 发布事件 )
Vue = {
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
/* new add start */
$on() {},
$once() {},
$off() {},
$emit() {},
/* new add end */
}
}
core/instance/lifecycle.js
- 给 Vue 的原型上添加 _update 方法 ( 组件更新时触发 )
- 给 Vue 的原型上添加 $forceUpdate 方法 ( 组件强制更新时触发 )
- 给 Vue 的原型上添加 $destroy 方法 ( 组件销毁时触发 )
Vue = {
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
/* new add start */
_update() {},
$forceUpdate() {},
$destroy() {},
/* new add end */
}
}
core/instance/render.js
- 给 Vue 的原型上添加 $nextTick 方法 ( 解决异步渲染获取不到 DOM 元素的问题 )
- 给 Vue 的原型上添加 _render 方法 ( 创建 虚拟DOM )
Vue = {
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
/* new add start */
$nextTick() {},
_render() {},
/* new add end */
}
}
core/instance/render-helpers/index.js
- 给 Vue 的原型上添加上一堆模板编译过程中的辅助方法
Vue = {
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
$nextTick() {},
_render() {},
/* new add start */
_o() {},
_n() {},
_s() {},
_l() {},
_t() {},
_q() {},
_i() {},
_m() {},
_f() {},
_k() {},
_b() {},
_v() {},
_e() {},
_u() {},
_g() {},
/* new add end */
}
}
core/index.js
- 给 Vue 的原型上添加 $isServer ( 判断是否是服务器渲染 )
- 给 Vue 的原型上添加 $ssrContext ( 获取服务器渲染的 虚拟DOM 上下文 )
- 给 Vue 的构造函数上添加 version ( 获取当前 Vue 版本 )
Vue = {
/* new add start */
version: '__VERSION__',
/* new add end */
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
$nextTick() {},
_render() {},
_o() {},
_n() {},
_s() {},
_l() {},
_t() {},
_q() {},
_i() {},
_m() {},
_f() {},
_k() {},
_b() {},
_v() {},
_e() {},
_u() {},
_g() {},
/* new add start */
$isServer: false,
$ssrContext: {},
/* new add end */
}
}
core/global-api/index.js
- 给 Vue 的构造函数上添加 config ( 内置一堆未定义的方法和属性 )
- 给 Vue 的构造函数上添加 util ( 内置 warn / extend / mergeOptions / defineReactive 方法 )
- 给 Vue 的构造函数上添加 set 方法 ( 同上给 Vue 的原型上添加 $set 方法一致 )
- 给 Vue 的构造函数上添加 delete 方法 ( 同上给 Vue 的原型上添加 $del 方法一致 )
- 给 Vue 的构造函数上添加 nextTick 方法 ( 同上给 Vue 的原型上添加 $nextTick 方法一致 )
- 给 Vue 的构造函数上添加 options
- 给 Vue 的构造函数上添加 options.components ( 放置全局组件 )
- 给 Vue 的构造函数上添加 options.directives ( 放置全局指令 )
- 给 Vue 的构造函数上添加 options.filters ( 放置全局过滤器 )
- 给 Vue 构造函数上的 options 添加 _base 指向 Vue构造函数
- 给 Vue 构造函数上的 options.components 全局组件 ( <keep-alive /> )
- 给 Vue 的构造函数上添加 use 方法 ( 注册全局插件 - Vue.use )
- 给 Vue 的构造函数上添加 mixin 方法 ( 注册全局混入 - Vue.mixin )
- 给 Vue 的构造函数上添加 extend 方法 ( 注册继承自 Vue构造函数 的子类 - Vue.extend )
- 给 Vue 的构造函数上添加 component 方法 ( 注册全局组件 - Vue.component )
- 给 Vue 的构造函数上添加 directive 方法 ( 注册全局指令 - Vue.directive )
- 给 Vue 的构造函数上添加 filter 方法 ( 注册全局过滤器 - Vue.filter )
Vue = {
version: '__VERSION__',
/* new add start */
config: {
// ...
},
util: {
warn,
extend,
mergeOptions,
defineReactive,
},
set(): {},
delete(): {},
nextTick(): {},
options: {
_base: Vue,
components: {
KeepAlive,
}
directives: {}
filters: {}
},
use() {},
mixin() {},
extend() {},
component() {},
directive() {},
filter() {},
/* new add end */
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
$nextTick() {},
_render() {},
_o() {},
_n() {},
_s() {},
_l() {},
_t() {},
_q() {},
_i() {},
_m() {},
_f() {},
_k() {},
_b() {},
_v() {},
_e() {},
_u() {},
_g() {},
$isServer: false,
$ssrContext: {},
}
}
platforms/web/runtime/index.js
- 修改 Vue 构造函数上 config 内的 mustUseProp 的方法 ( 判断当前 tag 是否必须使用属性 )
- 修改 Vue 构造函数上 config 内的 isReservedTag 的方法 ( 判断是否是保留标签 ( HTML标签 + SVG标签 ) )
- 修改 Vue 构造函数上 config 内的 isReservedAttr 的方法 ( 判断是否是保留属性 ( style + class ) )
- 修改 Vue 构造函数上 config 内的 getTagNamespace 的方法 ( 获取标签命名空间 )
- 修改 Vue 构造函数上 config 内的 isUnknownElement 的方法 ( 判断是否是个无效标签 )
- 给 Vue 构造函数上 options.components 添加 platformComponents 内的定义的全局组件 ( <Transition> + <TransitionGroup> )
- 给 Vue 构造函数上 options.directives 添加 platformDirectives 内的定义的全局指令 ( v-model + v-show )
- 给 Vue 的原型上添加 _patch_ 方法 ( diff 算法入口,提供虚拟节点的对比更新功能 )
- 给 Vue 的原型上添加 $mount 方法 ( 创建 渲染Watcher,以便于数据驱动视图 )
Vue = {
version: '__VERSION__',
config: {
/* update start */
mustUseProp() {},
isReservedTag() {},
isReservedAttr() {},
getTagNamespace() {},
isUnknownElement() {},
/* update end */
},
util: {
warn,
extend,
mergeOptions,
defineReactive,
},
set(): {},
delete(): {},
nextTick(): {},
options: {
_base: Vue,
components: {
KeepAlive,
/* new add start */
Transition,
TransitionGroup,
/* new add end */
}
/* new add start */
directives: {
'model',
'show',
}
/* new add end */
filters: {}
},
use() {},
mixin() {},
extend() {},
component() {},
directive() {},
filter() {},
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
$nextTick() {},
_render() {},
_o() {},
_n() {},
_s() {},
_l() {},
_t() {},
_q() {},
_i() {},
_m() {},
_f() {},
_k() {},
_b() {},
_v() {},
_e() {},
_u() {},
_g() {},
$isServer: false,
$ssrContext: {},
/* new add start */
__patch__() {},
$mount() {},
/* new add end */
}
}
platforms/web/entry-runtime-with-compiler.js
- 修改 Vue 原型上的 $mount 方法
- 给 Vue 的构造函数上添加 compile 方法
Vue = {
version: '__VERSION__',
config: {
mustUseProp() {},
isReservedTag() {},
isReservedAttr() {},
getTagNamespace() {},
isUnknownElement() {},
},
util: {
warn,
extend,
mergeOptions,
defineReactive,
},
set(): {},
delete(): {},
nextTick(): {},
options: {
_base: Vue,
components: {
KeepAlive,
Transition,
TransitionGroup,
}
directives: {
'model',
'show',
}
filters: {}
},
use() {},
mixin() {},
extend() {},
component() {},
directive() {},
filter() {},
/* new add start */
compile() {},
/* new add end */
prototype: {
_init() {},
$data: {},
$props: {},
$set() {},
$del() {},
$watch() {},
$on() {},
$once() {},
$off() {},
$emit() {},
_update() {},
$forceUpdate() {},
$destroy() {},
$nextTick() {},
_render() {},
_o() {},
_n() {},
_s() {},
_l() {},
_t() {},
_q() {},
_i() {},
_m() {},
_f() {},
_k() {},
_b() {},
_v() {},
_e() {},
_u() {},
_g() {},
$isServer: false,
$ssrContext: {},
__patch__() {},
/* update start */
$mount() {},
/* update end */
}
}
自此,一个完整的 Vue构造函数 就创建完毕了。