vue源码分析(六) 平台化

10/6/2018 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
1
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
}
1
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)
1
2
3

​ 这段代码就是通过extend函数给 Vue.options.directivesVue.options.components 扩展属性,我们再来看看 platformDirectivesplatformComponents 的定义,如下:

​ 源码目录: src/platforms/web/runtime/directives/index.js

export default {
  model,
  show
}
1
2
3
4

​ 源码目录: src/platforms/web/runtime/components/index.js

export default {
  Transition,
  TransitionGroup
}
1
2
3
4

​ 通过查看源码我们可以得出,最终生成的options 静态属为:

Vue.options = {
	components: {
		KeepAlive,
		Transition,
		TransitionGroup
	},
	directives: {
		model,
		show
	},
	filters: Object.create(null),
	_base: Vue
}
1
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
1
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)
}
1
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)
}
1
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 平台下的一些配置,主要总结起来有以下几点:

  1. 设置 web 平台的 Vue.config
  2. Vue.options 上混合了两个指令(directives),分别是 modelshow
  3. Vue.options 上混合了两个组件(components),分别是 TransitionTransitionGroup
  4. Vue.prototype 上添加了两个方法:__patch__$mount