Vue源码学习之Vue.use

98 阅读2分钟

Vue.use()是用来编写vue插件的。

通常在项目里面可以将一些全局的属性或者方法,通过插件的形式绑定到vue上面。

Vue 插件的作用

  1. 添加全局的方法或者属性。
  2. 添加全局资源,列如 directives, filters,transitions。
  3. 通过全局混入来添加一些组件选项。
  4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 来实现。
  5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。

先来看看vue.use()源码,以及我对源码理解的注释

/**
 * Vue.use()源码
 */
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)
        // 3-将Vue放进参数数组第一个位置
        args.unshift(this)
        // 4-执行插件的install函数
        if (typeof plugin.install === 'function') {
            // 如果我们传入一个对象,对象中包含 install 方法,那么我们就调用这个 plugin 的 install 方法并将整理好的数组当成参数传入 install 方法中
            plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
            // 如果我们传入的 plugin 就是一个函数,那么我们就直接调用这个函数并将整理好的数组当成参数传入
            plugin.apply(null, args)
        }
        // 5-将插件返回插件数组
        installedPlugins.push(plugin)
        // 6-返回Vue
        return this
    }
}
/**
 * toArray源码
 */
export function toArray(list: any, start?: number): Array<any> {
    start = start || 0
    let i = list.length - start
    const ret: Array = new Array(i)
    while (i--) {
        ret[i] = list[i + start]
    }
    return ret
}

如何编写一个自定义的插件

// 1-新建一个js文件
export const my_plugin = {
    // 注册插件时默认执行函数
    install: function (Vue, options) {
        // Vue 就是 vue 实例
        // options 就是 Vue.use(plugin,options) 传入的第二个参数 options

        // 1. 添加全局方法或属性
        Vue.myGlobalMethod = function () {
            // 逻辑...
        }

        // 2. 添加全局资源
        Vue.directive('my-directive', {
            bind(el, binding, vnode, oldVnode) {
                // 逻辑...
            }
        })

        // 3. 注入组件选项
        Vue.mixin({
            created: function () {
                // 逻辑...
            }
        })

        // 4. 添加实例方法
        Vue.prototype.$myMethod = function (methodOptions) {
            // 逻辑...
        }

    },
}
// 2-main.js引入并使用Vue.use()注册
import my_plugin from '...'
Vue.use(my_plugin)