Understanding Vue.use

Reference description link

First, I use the official scaffolding to create a new project vue init webpack vue-demo
and then I create two files index.js plugins.js.

I have two files placed in the src / classes / vue-use directory

Next to these two documents be written

// 文件:  src/classes/vue-use/plugins.js

const Plugin1 = {
    install(a, b, c) {
        console.log('Plugin1 第一个参数:', a);
        console.log('Plugin1 第二个参数:', b);
        console.log('Plugin1 第三个参数:', c);
    },
};

function Plugin2(a, b, c) {
    console.log('Plugin2 第一个参数:', a);
    console.log('Plugin2 第二个参数:', b);
    console.log('Plugin2 第三个参数:', c);
}

export { Plugin1, Plugin2 };

// 文件: src/classes/vue-use/index.js

import Vue from 'vue';

import { Plugin1, Plugin2 } from './plugins';

Vue.use(Plugin1, '参数1', '参数2');
Vue.use(Plugin2, '参数A', '参数B');

Then we main.js quote this code at the entrance file

// 文件: src/main.js

import Vue from 'vue';

import '@/classes/vue-use';
import App from './App';
import router from './router';

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
    el: '#app',
    router,
    render: h => h(App),
});

At this point we perform npm run dev open port 8080 open development and debugging tools can see the console output following information

It can be found in plugin1 we wrote in the three console install method are printed out, the first print out of the Vue objects, the second with the third we passed two parameters.

The plugin2 not install method, it is itself a method, it can print three parameters, the first is the Vue objects, the second with the third and we pass two parameters.

Source Analysis

// Vue源码文件路径:src/core/global-api/use.js

import { toArray } from '../util/index'

export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

We can see from the source code vue first determine whether the plug-in is registered, it does not allow duplicate registration.

And limit the plugin parameters are received Function | Object types.
For both types have different treatment.

First we pass parameters organized into arrays => const args = toArray (arguments, 1).

toArray source

// Vue源码文件路径:src/core/shared/util.js

export function toArray (list: any, start?: number): Array<any> {
  start = start || 0
  let i = list.length - start
  const ret: Array<any> = new Array(i)
  while (i--) {
    ret[i] = list[i + start]
  }
  return ret
}

Then the object is added to the starting positions Vue args.unshift the array (this), this point where the object Vue.

If we pass plugin (the first argument Vue.use) is a method of install. install method means that if we pass an object, the object contains the install method, then we call this plugin and tidied the array passed as a parameter in the install method. => Plugin.install.apply (plugin, args)

If we pass plugin is a function, then we call this function directly and tidied array as a parameter. => Plugin.apply (null, args)

After adding to this plug-in to plug-ins that have been added over the array, labeling already registered => installedPlugins.push (plugin)
finally returns Vue objects.

summary

Through the above analysis we can know, when we later write plug-ins can be in two ways.

One is to insert the package into a logical object is finally the last write operations Vue exposed to install code objects. The advantage of this is that you can easily add any parameters to install a more streamlined package function on this object, scalability is relatively high.

There is also a sucked all of the logic written as a function of exposure to Vue.
In fact, the principle of the two methods are the same, nothing more than the second is to install this plug-in directly as a function to handle.

Personally I feel that the first approach is reasonable.

export const Plugin = {
    install(Vue) {
        Vue.component...
        Vue.mixins...
        Vue...
        // 我们也可以在install里面执行其他函数,Vue会将this指向我们的插件
        console.log(this)  // {install: ...,utils: ...}
        this.utils(Vue)    // 执行utils函数
        console.log(this.COUNT) // 0
    },
    utils(Vue) {
        Vue...
        console.log(Vue)  // Vue
    },
    COUNT: 0    
}
// 我们可以在这个对象上添加参数,最终Vue只会执行install方法,而其他方法可以作为封装install方法的辅助函数

const test = 'test'
export function Plugin2(Vue) {
    Vue...
    console.log(test)  // 'test'
    // 注意如果插件编写成函数形式,那么Vue只会把this指向null,并不会指向这个函数
    console.log(this)  // null
}
// 这种方式我们只能在一个函数中编写插件逻辑,可封装性就不是那么强了

Guess you like

Origin www.cnblogs.com/cherishSmile/p/11091513.html