细读Vue2.6.14 Core 源码(1): 入口

684 阅读2分钟

细读Vue2.6.14 Core 源码(1): 入口

    /**
        @date 2021-07-20
        @description 入口
    */

壹(序)

今天决定停止每日一结:

  1. 有时候实在是不知道写什么;
  2. 输出的文章大都是很表面的知识,想要有一些自己的思考;
  3. 想要的是享受分享的这个过程,而不是完成任务;

最近几天在看Vue2.6.14源码,由于水平有限,看得比较慢,很多东西也不是很理解,需要反复拜读,想着还是记录一下,从入口处开始。

贰(入口)

首先我们需要找到入口处,从github clone 的源码结构看,核心源码应该是在 src 中,更核心的代码是在 src/core,而 src/core 里面有一个index.js,毫无疑问,我们从这里开始

import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'

// 初始化 Vue 全局API use, mixin, extend
initGlobalAPI(Vue)

// 与ssr相关,现在不关注
Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})
Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    return this.$vnode && this.$vnode.ssrContext
  }
})
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})

// 版本号
Vue.version = '__VERSION__'

export default Vue

很明显,这里主要的是Vue以及initGlobalAPI

叁(Vue)

先看引入 Vue时,会发生什么,进入到 Vue构造函数 声明的地方,可以看到除了声明 Vue构造函数,还做了很多事情

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'

function Vue (options) {
  // 调用_init函数
  this._init(options)
}
// Vue的prototype属性上添加_init
initMixin(Vue)
// Vue的prototype属性上添加 $data(此时为undefined), $props(此时为undefined), $set, $delete, $watch
stateMixin(Vue)
// Vue的prototype属性上添加 $on, $once, $off, $emit方法
eventsMixin(Vue)
// Vue的prototype属性上添加 _update, $forceUpdate, $destroy
lifecycleMixin(Vue)
// Vue的prototype属性上添加 _render, $nextTick, $destroy
renderMixin(Vue)

export default Vue

肆(initGlobalAPI)

然后看 initGlobalAPI,主要做的事情就是向 Vue 添加方法或属性,以及向 Vue.options 上添加属性

/* @flow */

import config from '../config'
import { initUse } from './use'
import { initMixin } from './mixin'
import { initExtend } from './extend'
import { initAssetRegisters } from './assets'
import { set, del } from '../observer/index'
import { ASSET_TYPES } from 'shared/constants'
import builtInComponents from '../components/index'
import { observe } from 'core/observer/index'

import {
  warn,
  extend,
  nextTick,
  mergeOptions,
  defineReactive
} from '../util/index'

export function initGlobalAPI (Vue: GlobalAPI) {
  const configDef = {}
  configDef.get = () => config
  // 定义Vue上config
  Object.defineProperty(Vue, 'config', configDef)

  // Vue上面的util方法
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }
  // 设置Vue上 set, delete, nextTick 与实例上 $set, $delete, $nextTick一样
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 2.6 explicit observable API
  Vue.observable = <>(obj: T): T => {
    observe(obj)
    return obj
  }

  // 设置Vue上 options 然后初始化 options上的值
  Vue.options = Object.create(null)
  
  /** 
    ASSET_TYPES = [
      'component',
      'directive',
      'filter'
    ]
  */
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })
  // Vue.options._base 就是 Vue 本身
  Vue.options._base = Vue
  // Vue.options.components 中添加 Keep-Alive
  extend(Vue.options.components, builtInComponents)

  // Vue上增加 use 属性方法
  initUse(Vue)
  // Vue上增加 mixin 属性方法
  initMixin(Vue)
  // Vue上增加 extend 属性方法, 用于创建子类
  initExtend(Vue)
  // Vue上增加 component, directive, filter 属性方法
  initAssetRegisters(Vue)
}

以上就是入口相关的代码,具体实现的东西还是挺多的,这里只关注了表面。

终(导航)

细读Vue2.6.14 Core 源码(1): 入口

细读Vue2.6.14 Core 源码(2): After Vue

细读Vue2.6.14 Core 源码(3): initGlobalAPI

细读Vue2.6.14 Core 源码(4): _init

细读Vue2.6.14 Core 源码(5): initState

细读Vue2.6.14 Core 源码(6): defineReactive

细读Vue2.6.14 Core 源码(7): $mount

细读Vue2.6.14 Core 源码(8): $createElement