汪图南
  • RAG

    • RAG
  • 快速入门
  • 高级技巧
前端面试之道
  • 打包工具

    • Webpack
    • Rollup
  • TypeScript

    • TypeScript基础
    • TypeScript类型挑战
  • CSS预编译器

    • SASS
  • 自动化测试

    • Vue应用测试
  • Vue2.0源码分析
  • Vue3.0源码分析
  • 数据结构和算法(基础)
  • LeetCode(刷题)
  • JavaScript书籍

    • 你不知道的JavaScript(上)
    • 你不知道的JavaScript(中下)
    • JavaScript数据结构和算法
    • JavaScript设计模式与开发实践
    • 深入理解ES6
  • Git书籍

    • 精通Git
Github
  • RAG

    • RAG
  • 快速入门
  • 高级技巧
前端面试之道
  • 打包工具

    • Webpack
    • Rollup
  • TypeScript

    • TypeScript基础
    • TypeScript类型挑战
  • CSS预编译器

    • SASS
  • 自动化测试

    • Vue应用测试
  • Vue2.0源码分析
  • Vue3.0源码分析
  • 数据结构和算法(基础)
  • LeetCode(刷题)
  • JavaScript书籍

    • 你不知道的JavaScript(上)
    • 你不知道的JavaScript(中下)
    • JavaScript数据结构和算法
    • JavaScript设计模式与开发实践
    • 深入理解ES6
  • Git书籍

    • 精通Git
Github
  • 介绍

    • 介绍和参考
  • 源码目录设计和架构设计

    • 设计
  • Rollup构建版本

    • Rollup基础知识
    • Vue中的Rollup构建
  • 从入口到构造函数整体流程

    • 整体流程
    • initGlobalAPI流程
    • initMixin流程
    • stateMixin流程
    • eventsMixin流程
    • lifecycleMixin流程
    • renderMixin流程
  • 响应式原理

    • 介绍
    • 前置核心概念
    • props处理
    • methods处理
    • data处理
    • computed处理
    • watch处理
    • 深入响应式原理
    • 依赖收集
    • 派发更新
    • nextTick实现原理
    • 变化侦测注意事项
    • 变化侦测API实现
  • 虚拟DOM和VNode

    • 虚拟DOM
    • VNode介绍
    • Diff算法
  • 组件化

    • 介绍
    • $mount方法
    • render和renderProxy
    • createElement
    • createComponent
    • 合并策略
    • update和patch
    • 组件生命周期
    • 组件注册
  • 编译原理

    • 介绍
    • compileToFunctions
    • parse模板解析
    • optimize优化
    • codegen代码生成
  • 扩展

    • 扩展
    • directive指令
    • filter过滤器
    • event事件处理
    • v-model
    • 插槽
    • Keep-Alive
    • Transition
    • Transition-Group
    • Vue.use插件机制
  • Vue-Router

    • 介绍
    • 路由安装
    • matcher介绍
    • 路由切换
    • 内置组件
    • 路由hooks钩子函数
  • Vuex

    • 介绍
    • Vuex安装
    • Vuex初始化
    • Vuex辅助API
    • Store实例API

Vue.use插件机制

在使用Vue开发应用程序的时候,我们经常使用第三方插件库来方便我们开发,例如:Vue-Router、Vuex和element-ui等等。

// main.js
import Vue from 'vue'
import Router from 'vue-router'
import Vuex from 'vuex'
import ElementUI from 'element-ui'

Vue.use(Router)
Vue.use(Vuex)
Vue.use(ElementUI)

new Vue({})

在new Vue之前,我们使用Vue.use方法来注册这些插件。其中,Vue.use作为一个全局方法,它是在initGlobalAPI方法内部通过调用initUse来注册这个全局方法的。

import { initUse } from './use'
export function initGlobalAPI (Vue: GlobalAPI) {
  // ...省略代码
  initUse(Vue)
  // ...省略代码
}

initUse方法的代码并不复杂,如下:

import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    // 1.检测是否已经注册了插件
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

   // 2.处理参数
    const args = toArray(arguments, 1)
    args.unshift(this)

    // 3.调用install方法
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

我们可以从以上代码中看出,当调用Vue.use时,它只要做三件事情:检查插件是否重复注册、处理插件参数和调用插件的install方法。

代码分析:

  • 检查插件是否重复注册:首先通过判断大Vue上的_installedPlugins属性是否已经存在当前插件,如果已经存在则直接返回;如果不存在才会执行后面的逻辑,假如我们有如下案例:
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)
Vue.use(Router)

多次调用Vue.use()方法注册同一个组件,只有第一个生效。

  • 处理插件参数:有些插件在注册的时候,可能需要我们额外的传递一些参数,例如element-ui。
import Vue from 'vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI, { 
  size: 'small',
  zIndex: 3000
})

按照上面的例子,Vue.use()方法的arguments数组的第一项为我们传递的插件,剩下的参数才是我们需要的,因此通过toArray方法把arguments类数组转成一个真正的数组。注意,此时args变量不包含插件这个元素,随后再把当前this也就是大Vue也传递进数组中。

// 演示使用,实际为大Vue的构造函数
const args = ['Vue', { size: 'small', zIndex: 3000}]
  • 调用插件的install方法:从官网插件我们知道,如果我们在开发一个Vue插件,必须为这个插件提供一个install方法,当调用Vue.use()方法的时候会自动调用此插件的install方法,并把第二步处理好的参数传递进去。假如,我们有如下插件代码:
// plugins.js
const plugin = {
  install (Vue, options) {
    console.log(options) // {msg: 'test use plugin'}

    // 其它逻辑
  }
}


// main.js
import Vue from 'vue'
import MyPlugin from './plugins.js'
Vue.use(MyPlugin, { msg: 'test use plugin' })

在install方法中,我们成功获取到了大Vue构造函数以及我们传递的参数,在随后我们就可以做一些其它事情,例如:注册公共组件、注册指令、添加公共方法以及全局Mixin混入等等。

最后更新时间: 2025/5/6 15:36
贡献者: wangtunan
Prev
Transition-Group