Vue中如何使用自定义插件(plugin)

1、在根目录src下创建一个libs文件夹,在libs文件夹下面创建一个myPlugins文件夹,用来存放我们的自定义插件,在myPlugins文件夹下面再创建一个index.js的文件。d54315878de0b7277fca52f289a5b3c0.png在index.js文件里面,我们创建一个myPlguin的对象,然后导出,最后在main.js中导入并且通过 use() 的方式使用即可,一个自定义插件便完成了,就是这么简单,好了,感谢大家的阅读。其余的事情就是在myPlugins/index.js文件里填充我们插件的功能代码了。

2、在libs/myPlugins/index.js文件里创建myPlguin对象并导出,给myPlguin对象添加一个install的方法,install方法的第一个参数是Vue实例,第二个是我们的配置项 options

const myPlguin = {};
myPlguin.install = function (Vue, options) {}
export default myPlguin;

3、接下来就是在main.js文件里引入,并使用 Vue.use()方法使用。

// 导入并使用我们的自定义插件
import myPLugin from './libs/myPlugin';
Vue.use(myPLugin);

接下来我们聊聊插件里可以做那些事情,这部分才是重点。

1、在自定义插件里面定义我们的全局方法

// 自定义组件里面定义的全局方法
Vue.myGlobalMethod = function () {
  console.log('自定义组件里面定义的全局方法');
}

然后我们在main.js文件中使用一下这个全局方法

// 导入并使用我们的自定义插件
import myPLugin from './libs/myPlugin';
Vue.use(myPLugin);
// 使用自定义插件里面的全局方法
Vue.myGlobalMethod();

结果如下图所示:64fbb1416481c7a1357252a840ddc342.png2、在自定义插件里面定义我们的全局自定义指令、过滤器以及全局组件

// 自定义组件里面定义的全局自定义指令
Vue.directive('my-directive', {
  bind() {
    console.log('自定义组件里面的自定义指令绑定成功');
  }
});

在组件中使用自定义指令

"shopList"></digui>

结果如下图所示:0f785e4ccc0c36fddb14b6afe6e6ee0e.png3、在自定义插件件里面加入全局混入

Vue.mixin({
    // 注入到每个组件的 created 生命周期中
  created() {
    console.log("created in plugin")
  },
})

结果如图所示:bbc0fbf4a201c3a4805dce95616dba0a.png4、在自定义插件件里面定义一些实例方法

Vue.prototype.$myMethod = function(){
  console.log("自定义组件里面定义的实例方法");
}

这样我们便可在项目中通过this的形式直接调用实例方法。我们在about页面的created生命周期中调用一下这个实例方法

created() {
  this.$myMethod();
},

结果如下图所示:36de71183e7244d2164b438bbf328a16.png

libs/myPlugin/index.js完整代码:

const myPlguin = {};

myPlguin.install = function (Vue, options) {
  // 自定义组件里面定义的全局方法
  Vue.myGlobalMethod = function () {
    console.log('自定义组件里面定义的全局方法');
  }
  // 自定义组件里面定义的全局自定义指令
  Vue.directive('my-directive', {
    bind() {
      console.log('自定义组件里面的自定义指令绑定成功');
    }
  });
  // 也可以加入全局的过滤器、全局组件

  // 加入全局混入
  Vue.mixin({
    // 注入到每个组件的 created 生命周期中
    created() {
      console.log("created in plugin")
    },
  })

  // // 定义一些实例方法
  Vue.prototype.$myMethod = function(){
    console.log("自定义组件里面定义的实例方法");
  }
}

export default myPlguin;

那么我们在Vue项目中使用第三方插件时,就通过Vue.use()来挂载,如ElementUI,但是axios就不需要,这是为什么呢?因为axios没有install方法。

// 引入ElementUI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

看看源码

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
}
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
  }
}

从源码中我们可以发现 vue 首先判断这个插件是否被注册过,不允许重复注册,并且接收的 plugin 参数的限制是 Function | Object 两种类型。对于这两种类型有不同的处理。首先将我们传入的参数整理成数组:const args = toArray(arguments, 1);再将 Vue 对象添加到这个数组的起始位置 args.unshift(this) ,这里的 this 指向 Vue 对象;如果我们传入的 plugin(Vue.use的第一个参数) 的 install 是一个方法。也就是说如果我们传入一个对象,对象中包含 install 方法,那么我们就调用这个 plugin 的 install 方法并将整理好的数组当成参数传入 install 方法中, plugin.install.apply(plugin, args);如果我们传入的 plugin 就是一个函数,那么我们就直接调用这个函数并将整理好的数组当成参数传入, plugin.apply(null, args);之后给这个插件添加至已经添加过的插件数组中,标示已经注册过installedPlugins.push(plugin);最后返回 Vue 对象。

通过以上分析我们可以知道,在我们以后编写插件的时候可以有两种方式。一种是将这个插件的逻辑封装成一个对象,最后将在 install 编写业务代码暴露给 Vue 对象。这样做的好处是可以添加任意参数在这个对象上方便将 install 函数封装得更加精简,可拓展性也比较高。还有一种则是将所有逻辑都编写成一个函数暴露给 Vue。其实两种方法原理都一样,无非第二种就是将这个插件直接当成 install 函数来处理。个人觉得第一种方式比较合理。

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
}
// 这种方式我们只能在一个函数中编写插件逻辑,可封装性就不是那么强了
bcb79f1a79e78ff018c6e4e5fd78105f.png
Logo

前往低代码交流专区

更多推荐