Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 源码分析(构造函数) #11

Open
yangdui opened this issue May 16, 2020 · 0 comments
Open

Vue 源码分析(构造函数) #11

yangdui opened this issue May 16, 2020 · 0 comments

Comments

@yangdui
Copy link
Owner

yangdui commented May 16, 2020

Vue 源码分析(构造函数)

寻找构造函数

我们知道 Vue 通过 new Vue 开始的,Vue 是一个构造函数。

Vue 的入口是在 src/platforms/web/entry-runtime-with-compiler.js ,在文件的最后导出 Vue

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'

const idToTemplate = cached(id => {
  const el = query(id)
  return el && el.innerHTML
})

......

export default Vue

其中 Vue 又是通过 import Vue from './runtime/index' 导入的。

import Vue from 'core/index'
import config from 'core/config'
import { extend, noop } from 'shared/util'
import { mountComponent } from 'core/instance/lifecycle'
import { devtools, inBrowser } from 'core/util/index'

.....

export default Vue

./runtime/index 也是通过 import Vue from 'core/index' 导入的,继续在 /core/index 寻找,最终是在 ./instance/index 定义的

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
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

Vue 本身很简单,调用自身 _init 函数。

构造函数属性和方法

从入口文件到最终定义 Vue 的文件中,在构造函数 Vue 上添加了很多属性和方法。在这里不探究具体作用,知道添加了哪些。

src/platforms/web/entry-runtime-with-compiler.js 添加了

  • 在 Vue.prototype 上重新定义了 $mount 函数
  • 在 Vue 对象上添加了 compileToFunctions, Vue.compile = compileToFunctions

runtime/index.js

  • 在 Vue.prototype 上重新定义了 $mount 函数
  • Vue.config 添加属性
  • Vue.options.directives 添加指令:model 和 show
  • Vue.options.components 添加原生组件:Transition 和 TransitionGroup
  • Vue.prototype 添加 __patch__ 函数
  • Vue.prototype 添加 $mount 函数

core/index.js

  • 首先通过 Object.defineProperty 在 Vue 添加 FunctionalRenderContext,以及在 Vue.prototype 添加 $ssrContext、$isServer

  • 通过 initGlobalAPI 函数初始化全局 API

    • 在 Vue 上添加 config,Object.defineProperty(Vue, 'config', configDef)

    • 在 Vue 上添加 util

      Vue.util = {
          warn,
          extend,
          mergeOptions,
          defineReactive
        }
      
    • 添加三个重要的 API:

        Vue.set = set
        Vue.delete = del
        Vue.nextTick = nextTick
      
    • 添加 observable

      Vue.observable = <T>(obj: T): T => {
          observe(obj)
          return obj
        }
       
      
    • 添加 options 对象,并在 options 对象上初始化 componentsdirectives、filters 为空对象

      Vue.options = Object.create(null)
        ASSET_TYPES.forEach(type => {
          Vue.options[type + 's'] = Object.create(null)
        })
      
    • 在 Vue.options 添加 _base

      Vue.options._base = Vue
      
    • 在 Vue.options.components 上添加 KeepAlive

      extend(Vue.options.components, builtInComponents)
      
    • 最后通过四个函数添加了重要的四个全局 API

      initUse(Vue) // Vue.use
      initMixin(Vue) // Vue.mixin
      initExtend(Vue) // Vue.extend
      initAssetRegisters(Vue) // 重新定义 Vue.component, Vue.directive, Vue.filter
      

core/instance/index

  • 通过 initMixin 函数添加 _init 函数,这就就是 Vue 构造函数调用的 _init

  • 通过 stateMixin 函数在 Vue.prototype 添加 $data、$props、$set、$delete、$watch

  • 通过 eventsMixin 函数在 Vue.prototype 添加关于事件的方法:$on、$once、$off、$emit

  • 通过 lifecycleMixin 函数在 Vue.prototype 添加生命周期的方法:_update、$forceUpdate、$destroy

  • 通过 renderMixin 函数在 Vue.prototype 添加渲染相关方法:$nextTick、_render ,在 renderMixin 函数中还调用了 installRenderHelpers 函数

    export function installRenderHelpers (target: any) {
      target._o = markOnce
      target._n = toNumber
      target._s = toString
      target._l = renderList
      target._t = renderSlot
      target._q = looseEqual
      target._i = looseIndexOf
      target._m = renderStatic
      target._f = resolveFilter
      target._k = checkKeyCodes
      target._b = bindObjectProps
      target._v = createTextVNode
      target._e = createEmptyVNode
      target._u = resolveScopedSlots
      target._g = bindObjectListeners
      target._d = bindDynamicKeys
      target._p = prependModifier
    }
    

Vue 前期准备工作和初始化已经完成

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant