最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

深入Vue.js从源码开始(二)

XAMPP下载 admin 626浏览 0评论
 从入口开始
我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/entry-runtime-with-compiler.js:

摘选entry-runtime-with-compiler.js

import config from ‘core/config’
import { warn, cached } from ‘core/util/index’
import { mark, measure } from ‘core/util/perf’

//主角在这里
import Vue from ‘./runtime/index’
import { query } from ‘./util/index’
import { compileToFunctions } from ‘./compiler/index’
import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from ‘./util/compat’

Vue 的入口
在这个入口 JS 的上方我们可以找到 Vue 的来源:import Vue from ‘./runtime/index’,我们先来看一下这块儿的实现,它定义在 src/platforms/web/runtime/index.js 中:

import Vue from ‘core/index’
import config from ‘core/config’
import { extend, noop } from ‘shared/util’

这里关键的代码是 import Vue from ‘core/index’是真正初始化 Vue 的地方[c/core/index.js]

import Vue from ‘./instance/index’
import { initGlobalAPI } from ‘./global-api/index’

这里有 2 处关键的代码,import Vue from ‘./instance/index'(./指的是当前目录) 和 initGlobalAPI(Vue),初始化全局 Vue API,我们先来看第一部分,在 src/core/instance/index.js 中:

Vue 的定义
import { initMixin } from ‘./init’
import { stateMixin } from ‘./state’
import { renderMixin } from ‘./render’
import { eventsMixin } from ‘./events’
import { lifecycleMixin } from ‘.fecycle’
import { warn } from ‘../util/index’

function Vue (options) {
if (process.env.NODE_ENV !== ‘production’ &&
!(this instanceof Vue)
) {
warn(‘Vue is a constructor and should be called with the `new` keyword’)
}
this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue
1

在这里,我们终于看到了 Vue 的庐山真面目,它实际上就是一个用 Function 实现的类,我们只能通过 new Vue 去实例化它

为何 Vue 不用 ES6 的 Class 去实现呢?我们往后看这里有很多 xxxMixin 的函数调用,并把 Vue 当参数传入,它们的功能都是给 Vue 的 prototype 上扩展一些方法(这里具体的细节会在之后的文章介绍,这里不展开),Vue 按功能把这些扩展分散到多个模块中去实现,而不是在一个模块里实现所有,这种方式是用 Class 难以实现的。这么做的好处是非常方便代码的维护和管理,这种编程技巧也非常值得我们去学习。

initGlobalAPI
Vue.js 在整个初始化过程中,除了给它的原型 prototype 上扩展方法,还会给 Vue 这个对象本身扩展全局的静态方法,它的定义在 src/core/global-api/index.js 中:

export function initGlobalAPI (Vue: GlobalAPI) {
// config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== ‘production’) {
configDef.set = () => {
warn(
‘Do not replace the Vue.config object, set individual fields instead.’
)
}
}
Object.defineProperty(Vue, ‘config’, configDef)

// exposed util methods.
// NOTE: these are not considered part of the public API – avoid relying on
// them unless you are aware of the risk.
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}

Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick

Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + ‘s’] = Object.create(null)
})

// this is used to identify the “base” constructor to extend all plain-object
// components with in Weex’s multi-instance scenarios.
Vue.options._base = Vue

extend(Vue.options.components, builtInComponents)

initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
}

这里就是在 Vue 上扩展的一些全局方法的定义,Vue 官网中关于全局 API 都可以在这里找到,这里不会介绍细节,会在之后的章节我们具体介绍到某个 API 的时候会详细介绍。有一点要注意的是,Vue.util 暴露的方法最好不要依赖,因为它可能经常会发生变化,是不稳定的。

转载请注明:XAMPP中文组官网 » 深入Vue.js从源码开始(二)

您必须 登录 才能发表评论!