vue源码分析(六) 平台化
# 1. 概述
在 vue源码分析(一) vue目录结构 (opens new window) 章节中,我们知道 Vue.js
支持 Web
平台和 Weex
平台。
说明:关于Weex 和 Web 的平台差异,请移步到这里学习。
# 2. 平台运行时全局配置
接下来我们回到 src/platforms/web/runtime/index.js
,源码一开始就对全局配置进行覆盖,代码如下:
源码目录: src/platforms/web/runtime/index.js
// install platform specific utils
Vue.config.mustUseProp = mustUseProp
Vue.config.isReservedTag = isReservedTag
Vue.config.isReservedAttr = isReservedAttr
Vue.config.getTagNamespace = getTagNamespace
Vue.config.isUnknownElement = isUnknownElement
2
3
4
5
6
说明:关于这些配置的说明,我们下一章 (opens new window)会详细说明。
# 3. 平台运行时指令和组件
上一章 —— vue源码分析(五) 静态属性和方法 (opens new window) 我们分析过 Vue
的静态属性 options
的情况,上一章最终生成的 options
静态属性如下:
Vue.options = {
components: {
KeepAlive
},
directives: Object.create(null),
filters: Object.create(null),
_base: Vue
}
2
3
4
5
6
7
8
接下来执行的两句代码是给 Vue
添加平台运行时指令和组件,代码如下:
源码目录: src/platforms/web/runtime/index.js
// install platform runtime directives & components
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)
2
3
这段代码就是通过extend函数给 Vue.options.directives
和 Vue.options.components
扩展属性,我们再来看看 platformDirectives
和 platformComponents
的定义,如下:
源码目录: src/platforms/web/runtime/directives/index.js
export default {
model,
show
}
2
3
4
源码目录: src/platforms/web/runtime/components/index.js
export default {
Transition,
TransitionGroup
}
2
3
4
通过查看源码我们可以得出,最终生成的options
静态属为:
Vue.options = {
components: {
KeepAlive,
Transition,
TransitionGroup
},
directives: {
model,
show
},
filters: Object.create(null),
_base: Vue
}
2
3
4
5
6
7
8
9
10
11
12
13
说明:关于这些指令和组件,我们后面章节会详细说明。
# 4. __patch__
实例方法
我们继续分析接下来执行的代码,如下:
源码目录: src/platforms/web/runtime/index.js
// install platform patch function
// 初始化path方法
Vue.prototype.__patch__ = inBrowser ? patch : noop
2
3
这段代码是在 Vue.prototype
上添加 __patch__
方法,如果在浏览器环境运行的话,这个方法的值为 patch
函数,否则是一个空函数 noop
。
说明:关于patch
,我们后面章节会详细说明。
# 5. $mount
实例方法
接着在 Vue.prototype
上添加了 $mount
方法,原型上声明的 $mount
方法在,这个方法会被runtime only
版本和 runtime compiler
版本中复用。
源码目录: src/platforms/web/runtime/index.js
// public mount method
Vue.prototype.$mount = function (
el?: string | Element, // 真实的dom 或者 是string
hydrating?: boolean // 新的虚拟dom vnode
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
2
3
4
5
6
7
8
# 6. devtools
最后是设置 vue-devtools
的全局钩子,它被包裹在 setTimeout
中,代码如下:
源码目录: src/platforms/web/runtime/index.js
// devtools global hook
/* istanbul ignore next */
if (inBrowser) {
setTimeout(() => {
if (config.devtools) {
if (devtools) {
devtools.emit('init', Vue)
} else if (
process.env.NODE_ENV !== 'production' &&
process.env.NODE_ENV !== 'test'
) {
console[console.info ? 'info' : 'log'](
'Download the Vue Devtools extension for a better development experience:\n' +
'https://github.com/vuejs/vue-devtools'
)
}
}
if (process.env.NODE_ENV !== 'production' &&
process.env.NODE_ENV !== 'test' &&
config.productionTip !== false &&
typeof console !== 'undefined'
) {
console[console.info ? 'info' : 'log'](
`You are running Vue in development mode.\n` +
`Make sure to turn on production mode when deploying for production.\n` +
`See more tips at https://vuejs.org/guide/deployment.html`
)
}
}, 0)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 7. 总结
文件 src/platforms/web/runtime/index.js
文件主要是 web
平台下的一些配置,主要总结起来有以下几点:
- 设置
web
平台的Vue.config
。 - 在
Vue.options
上混合了两个指令(directives
),分别是model
和show
。 - 在
Vue.options
上混合了两个组件(components
),分别是Transition
和TransitionGroup
。 - 在
Vue.prototype
上添加了两个方法:__patch__
和$mount
。