1、首先我们要先了解下Vue.use(plugin)的用法。

  • 参数

    • {Object | Function} plugin
  • 用法

    安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。

    该方法需要在调用 new Vue() 之前被调用。

    当 install 方法被同一个插件多次调用,插件将只会被安装一次。

下面是vue2.0源码,使用vue.use(plugins)其实是将plugin放到vue构造器的_installedPlugins属性里,防止重复安装,并且以Vue.component的方式做全局组件。

Vue.use = function (plugin) {
    // 获取vue构造器当前已经use的组件,如果组件已经存在则返回当前vue对象,避免同一组件重复use
    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    // 将类数组对象转化成数组,满足apply(对象, 数组)
    var 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);
    }
    // 填充到vue的_installedPlugins中
    installedPlugins.push(plugin);
    return this
  };

plugin必须是个对象或者方法,对象的话必须存在install(), 方法的话默认该方法就是install();

2、如何封装自己的组件

​ 这里分自写组件库使用和自己项目上使用。

  1. 自写组件库使用

    1. 参考element-ui,具体分层和代码如下

      1) 按照包格式编写组件。
      内容:

      2)各文件内容

      /dbutton/src/main.vue

      <template>
        <button class="btn">点击</button>
      </template>
      
      <script>
      export default {
        name: "Dbutton", // 这里名称建议为组件包名称,首字母大写
        components: {},
        data() {
          return {};
        },
        computed: {},
        watch: {},
        created() {},
        mounted() {},
        methods: {},
      };
      </script>
      <style lang='scss' scoped>
      //@import url(); 引入公共css类
      .btn {
        padding: 12px 20px;
        font-size: 16px;
        background: blue;
        border-radius: 5px;
        color: #ffffff;
        &:hover {
          background: red;
        }
      }
      </style>
      

      /dbutton/src/index.js

      import Dbutton from './src/main';
      
      // 给单独的组件添加install事件,便于按需注册
      Dbutton.install = Vue =>{
        Vue.component(Dbutton.name, Dbutton);
      }
      
      export default Dbutton;
      

      /dbutton/src/install.js

      import Dbutton from './dbutton/index.js';
      // 这里为组件数组,便于install方法循环
      const commonComponnet = [
          Dbutton
      ]
      
      // 注册全局install方法,这里的install会循环遍历component,给vue实例注册全局组件
      const install = function (Vue, options = {}) {
          commonComponnet.forEach(component => {
              Vue.component(component.name, component)
          })
      }
      
      // 导出对象,对象属性为各组件,以及install方法
      export default {
          install,
          Dbutton
      }
      

      3) main.js使用

      全局引入。这里使用use不仅会调用全局的install(),也会调用各组件的install(),但是没有影响。vue.use()已经给我们做了处理,相同组件只允许注册一次。

      import HavikerUI from './components/install';
      Vue.use(HavikerUI);
      

      局部引入。这样的话就只会调用Dbutton的install().

      import HavikerUI from './components/install';
      
      const { install, Dbutton } = HavikerUI;
      Vue.use(Dbutton);
      
  2. 项目使用

    项目上所使用的组件分为两种,全局组件和局部组件。局部组件在对应页面import后使用即可,全局组件去掉/dbutton/src/index.js,修改/dbutton/src/install.js的引入,改为import Dbutton from './src/main'; 即可。

  3. 如何开发插件
    Vue.js 要求插件应该有一个公开方法 install。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。
    在 install 方法里面,便可以做相关的处理:
    添加全局方法或者属性
    添加全局资源:指令/过滤器/过渡等,
    通过全局 mixin 方法添加一些组件选项,
    添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
    一个库,提供自己的 API,同时提供上面提到的一个或多个功能

MyPlugin.install = function (Vue, 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) {
    // 逻辑...
  }
}