源码版本:2.0.5前端
让咱们用一段demo展现一下这三个概念:vue
//HTML <div id="app"> {{ message }} </div>
//JS var vm = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })
其中:api
Vue: Vue的构造器浏览器
vm : 实例 (实例名能够任意取,这里咱们便于理解保持和vue文档一致)app
new Vue(options): 选项(options)即为传入构造器里的配置选项。(data, methods,computed,created...)函数
当咱们了解这三个概念,将有助于咱们去理解vue的api文档工具
全局配置: 以 Vue.config.xx 的形式去访问和修改ui
全局API: 以Vue.xx 的形式去访问和修改this
选项: 以 var vm = new Vue(options) 的形式将options传入构造器
实例属性/方法: 以vm.$xx的方式去访问 (前缀$,为了不用户data/methods等解析后绑定的api 和 默认api冲突)
从api文档中咱们能够了解到,当咱们引入vue.js, 咱们仅仅引入了一个构造函数(Vue)
引入了构造函数后,咱们有几种使用方式
将咱们自定义的选项,传入构造器。 当new Vue(options)时,会自动运行vm._init方法
解析各类选项
调用beforeCreate 和created 上绑定的钩子函数
将数据项(data,computed,props)和methods等绑到实例上
调用vm.$mount方法,来执行模板渲染
返回一个实例对象 vm
实际上,咱们使用vue.js来开发时,主要就是配置不一样的options提供Vue构造器解析,实现不一样的业务功能。
src/core/index.js
import Vue from './instance/index' import { initGlobalAPI } from './global-api/index' import { isServerRendering } from 'core/util/env' initGlobalAPI(Vue) Object.defineProperty(Vue.prototype, '$isServer', { get: isServerRendering }) Vue.version = '__VERSION__' export default Vue
Vue源码的主入口主要作三件事
1.引用 ./instance/index 中暴露的Vue构造器
2.调用initGlobalAPI方法,定义全局资源
3.暴露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 = () => { util.warn( 'Do not replace the Vue.config object, set individual fields instead.' ) } } Object.defineProperty(Vue, 'config', configDef) Vue.util = util Vue.set = set Vue.delete = del Vue.nextTick = util.nextTick Vue.options = Object.create(null) config._assetTypes.forEach(type => { Vue.options[type + 's'] = Object.create(null) }) Vue.options._base = Vue util.extend(Vue.options.components, builtInComponents) initUse(Vue) initMixin(Vue) initExtend(Vue) initAssetRegisters(Vue) }
initGlobal的代码就是对Vue进行各类方法和属性定义
【Vue.config】 各类全局配置项
【Vue.util】 各类工具函数,还有一些兼容性的标志位(哇,不用本身判断浏览器了,Vue已经判断好了)
【Vue.set/delete】 这个你文档应该见过
【Vue.nextTick】
【Vue.options】 这个options和咱们上面用来构造实例的options不同。这个是Vue默认提供的资源(组件指令过滤器)。
【Vue.use】 经过initUse方法定义
【Vue.mixin】 经过initMixin方法定义
【Vue.extend】经过initExtend方法定义
这些定义的全局api可好玩了,日常咱们可能是用实例上的方法。其实构造器上也绑了很多好用的方法。
有兴趣的同窗,能够用下方代码去探究一下
在你的vue项目里,谷歌命令行键入 Object.getOwnPropertyNames(Vue) //能够看定义在对象上的全部属性名/方法名 Vue.config Vue.util Vue.set.toString() //咱们日常在控制台上是看不了一个函数到底源码怎么样的,用toString()就能够啦
src/core/instance/index.js
//构造函数,当new Vue(options) 会自动执行这个函数 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)
这里就不一个一个函数展开了
构造函数里其实就一句话,this._init(options)
initMixin之类的方法,定义了实例上的方法,下面给出一个探索地图,以供探究源码
咱们能够看到 以 "_"为开头的方法,多半是Vue内部使用,但不公开的api。
以“$” 为开头的方法,是文档中公开给用户使用的默认api
至此,咱们对Vue的结构有了个初步的了解,以及相关api的原始出处有了初步了解。
在学习的过程当中,参考了两位大牛的文章,收益良多
囧克斯 Vue.js源码学习笔记
王鹤 Vue.js 2.0源码解析以前端渲染篇