Vue 源码解读(5)—— 全局 API

目标

深入理解以下全局 API 的实现原理。

  • Vue.use

  • Vue.mixin

  • Vue.component

  • Vue.filter

  • Vue.directive

  • VUe.extend

  • Vue.set

  • Vue.delete

  • Vue.nextTick

源码解读

从该系列的第一篇文章 Vue 源码解读(1)—— 前言 中的 源码目录结构 介绍中可以得知,Vue 的众多全局 API 的实现大部分都放在 /src/core/global-api 目录下。这些全局 API 源码阅读入口则是在 /src/core/global-api/index.js 文件中。

入口

/src/core/global-api/index.js

/**
 * 初始化 Vue 的众多全局 API,比如:
 *   默认配置:Vue.config
 *   工具方法:Vue.util.xx
 *   Vue.set、Vue.delete、Vue.nextTick、Vue.observable
 *   Vue.options.components、Vue.options.directives、Vue.options.filters、Vue.options._base
 *   Vue.use、Vue.extend、Vue.mixin、Vue.component、Vue.directive、Vue.filter
 *   
 */
export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  // Vue 的众多默认配置项
  configDef.get = () => config

  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }

  // Vue.config
  Object.defineProperty(Vue, 'config', configDef)

  /**
   * 暴露一些工具方法,轻易不要使用这些工具方法,处理你很清楚这些工具方法,以及知道使用的风险
   */
  Vue.util = {
    // 警告日志
    warn,
    // 类似选项合并
    extend,
    // 合并选项
    mergeOptions,
    // 设置响应式
    defineReactive
  }

  // Vue.set / delete / nextTick
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 响应式方法
  Vue.observable = <T>(obj: T): T => {
    observe(obj)
    return obj
  }

  // Vue.options.compoents/directives/filter
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // 将 Vue 构造函数挂载到 Vue.options._base 上
  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)
} 

Vue.use

/src/core/global-api/use.js

/**
 * 定义 Vue.use,负责为 Vue 安装插件,做了以下两件事:
 *   1、判断插件是否已经被安装,如果安装则直接结束
 *   2、安装插件,执行插件的 install 方法
 * @param {*} plugin install 方法 或者 包含 install 方法的对象
 * @returns Vue 实例
 */
Vue.use = function (plugin: Function | Object) {
  // 已经安装过的插件列表
  const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
  // 判断 plugin 是否已经安装,保证不重复安装
  if (installedPlugins.indexOf(plugin) > -1) {
    return this
  }

  // 将 Vue 构造函数放到第一个参数位置,然后将这些参数传递给 install 方法
  const args = toArray(arguments, 1)
  args.unshift(this)

  if (typeof plugin.install === 'function') {
    // plugin 是一个对象,则执行其 install 方法安装插件
    plugin.install.apply(plugin, args)
  } else if (typeof plugin === 'function') {
    // 执行直接 plugin 方法安装插件
    plugin.apply(null, args)
  }
  // 在 插件列表中 添加新安装的插件
  installedPlugins.push(plugin)
  return this
} 

Vue.mixin

/src/core/global-api/mixin.js

/**
 * 定义 Vue.mixin,负责全局混入选项,影响之后所有创建的 Vue 实例,这些实例会合并全局混入的选项
 * @param {*} mixin Vue 配置对象
 * @returns 返回 Vue 实例
 */
Vue.mixin = function (mixin: Object) {
  // 在 Vue 的默认配置项上合并 mixin 对象
  this.options = mergeOptions(this.options, mixin)
  return this
} 

mergeOpt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值