源码目录:src/core/instance/index.js
可以看到Vue其实就是一个函数(function),new 作为JavaScript中实例化对象的关键字,所以我们在vue项目中的main.js文件中都会new Vue()来创建Vue类。
instanceof 可以用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
当不是通过关键字创建Vue实例会走warn函数报错,然后调用_init()方法,该方法在src/core/instance/init.js中定义,我们找到该函数看看init内做了什么。
Vue.prototype._init = function (options?: Object) {const vm: Component = this// a uidvm._uid = uid++let startTag, endTag/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {startTag = `vue-perf-start:${vm._uid}`endTag = `vue-perf-end:${vm._uid}`mark(startTag)}// a flag to avoid this being observedvm._isVue = true// merge optionsif (options && options._isComponent) {// optimize internal component instantiation// since dynamic options merging is pretty slow, and none of the// internal component options needs special treatment.initInternalComponent(vm, options)} else {vm.$options = mergeOptions(resolveConstructorOptions(vm.constructor),options || {},vm)}/* istanbul ignore else */if (process.env.NODE_ENV !== 'production') {initProxy(vm)} else {vm._renderProxy = vm}// expose real selfvm._self = vminitLifecycle(vm)initEvents(vm)initRender(vm)callHook(vm, 'beforeCreate')initInjections(vm) // resolve injections before data/propsinitState(vm)initProvide(vm) // resolve provide after data/propscallHook(vm, 'created')/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {vm._name = formatComponentName(vm, false)mark(endTag)measure(`vue ${vm._name} init`, startTag, endTag)}if (vm.$options.el) {vm.$mount(vm.$options.el)}}
可以看到_init函数在Vue的原型上定义,Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。
然后如果检测到传入的options中有el属性(即为根节点),则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM,那么接下来我们来分析 Vue 的挂载过程。
