源码目录:src/core/instance/index.js
    image.png
    可以看到Vue其实就是一个函数(function),new 作为JavaScript中实例化对象的关键字,所以我们在vue项目中的main.js文件中都会new Vue()来创建Vue类。

    instanceof 可以用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

    当不是通过关键字创建Vue实例会走warn函数报错,然后调用_init()方法,该方法在src/core/instance/init.js中定义,我们找到该函数看看init内做了什么。

    1. Vue.prototype._init = function (options?: Object) {
    2. const vm: Component = this
    3. // a uid
    4. vm._uid = uid++
    5. let startTag, endTag
    6. /* istanbul ignore if */
    7. if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    8. startTag = `vue-perf-start:${vm._uid}`
    9. endTag = `vue-perf-end:${vm._uid}`
    10. mark(startTag)
    11. }
    12. // a flag to avoid this being observed
    13. vm._isVue = true
    14. // merge options
    15. if (options && options._isComponent) {
    16. // optimize internal component instantiation
    17. // since dynamic options merging is pretty slow, and none of the
    18. // internal component options needs special treatment.
    19. initInternalComponent(vm, options)
    20. } else {
    21. vm.$options = mergeOptions(
    22. resolveConstructorOptions(vm.constructor),
    23. options || {},
    24. vm
    25. )
    26. }
    27. /* istanbul ignore else */
    28. if (process.env.NODE_ENV !== 'production') {
    29. initProxy(vm)
    30. } else {
    31. vm._renderProxy = vm
    32. }
    33. // expose real self
    34. vm._self = vm
    35. initLifecycle(vm)
    36. initEvents(vm)
    37. initRender(vm)
    38. callHook(vm, 'beforeCreate')
    39. initInjections(vm) // resolve injections before data/props
    40. initState(vm)
    41. initProvide(vm) // resolve provide after data/props
    42. callHook(vm, 'created')
    43. /* istanbul ignore if */
    44. if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    45. vm._name = formatComponentName(vm, false)
    46. mark(endTag)
    47. measure(`vue ${vm._name} init`, startTag, endTag)
    48. }
    49. if (vm.$options.el) {
    50. vm.$mount(vm.$options.el)
    51. }
    52. }

    可以看到_init函数在Vue的原型上定义,Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。

    然后如果检测到传入的options中有el属性(即为根节点),则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM,那么接下来我们来分析 Vue 的挂载过程。