vue源码分析-从new Vue开始

初学vue,你得知道我们是从new Vue开始的:

new Vue({
   
  el: '#app',
  data: obj,
  ...
})

那你觉得是不是很有意思,咱们new Vue之后,就可以使用他那么多的功能,可见Vue是暴出来的一个一个功能类函数,我们进入源码一探究竟:

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'
/** * 添加全局的API */
initGlobalAPI(Vue)
/** * 服务端渲染需要 */
Object.defineProperty(Vue.prototype, '$isServer', {
   
  get: isServerRendering
})
/** * 服务端渲染需要 */
Object.defineProperty(Vue.prototype, '$ssrContext', {
   
  get () {
   
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})
/** * 服务端渲染需要 */
Object.defineProperty(Vue, 'FunctionalRenderContext', {
   
  value: FunctionalRenderContext
})
/** * vue版本号 这里的'__VERSION__'为占位符,发布版本时将被自动替换 */
Vue.version = '__VERSION__'
export default Vue

那么我们看到咱们的核心Vue来自'./instance/index'那我们再去一探究竟,可想而知里面必定有一个Vue函数类

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'

// Vue构造函数必须使用new关键字实例化, 否则会抛出一个警告, 实例化Vue的时候会调用_init方法初始化
// 这里options也是.vue文件中暴露出的对象
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

可以看到里面有一个function Vue功能类,而且里面加载了initMixin,stateMixin等,这几个方法分别传入了Vue来初始化一些功能。
另外我们可以在入口文件出看到initGlobalAPI这个方法,那么我们打开initGlobalAPI所在的位置:./global-api/index

......
export function initGlobalAPI (Vue: GlobalAPI) {
   
  // config
  // 提供获取配置项的方法, 不允许在这里设置配置项
  const configDef = {
   }
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
   
    configDef.set = () => {
   
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  // 注册全局工具API, 只对Vue生效。
  Vue.util = {
   
    warn,
    extend,
    mergeOptions,
    defineReactive
  }
  //定义全局属性
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 初始化options
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
   
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  // 用_base属性来挂载Vue构造器
  Vue.options._base = Vue

  extend(Vue.options.components, builtInComponents)
  //定义全局方法
  initUse(Vue) // Vue.use
  initMixin(Vue) // Vue.mixin
  initExtend(Vue) // Vue.extend
  initAssetRegisters(Vue)
}

可见暴露出多个方法给全局,而Vue.util是一些工具方法:

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 {
   
  warn,
  extend,
  nextTick,
  mergeOptions,
  defineReactive
} from '../util/index'

那么我们回到Vue功能函数类上:

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'

// Vue构造函数必须使用new关键字实例化, 否则会抛出一个警告, 实例化Vue的时候会调用_init方法初始化
// 这里options也是.vue文件中暴露出的对象
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

我们可以看到initMixin(Vue)执行了,那么我们去读一下init的源码:

参考Vue3源码视频讲解:进入学习

import config from '../config'
import {
    initProxy } from './proxy'
import {
    initState } from './state'
import {
    initRender } from './render'
import {
    initEvents } from './events'
import {
    mark, measure } from '../util/perf'
import {
    initLifecycle, callHook } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值