实现一个简单的Vue插件
我们先看官方文档对插件的描述
插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种:
1.添加全局方法或者属性,如: vue-custom-element
2.添加全局资源:指令/过滤器/过渡等,如 vue-touch
3.通过全局 mixin 方法添加一些组件选项,如: vue-router
4.添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
5.一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router
Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局自定义指令
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 添加全局mixin
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
实现一个可以多种途径调用的Toast插件
我们先实现一个toast组件 toast.vue
<template>
<div class="my-toast" v-show="show">{{text}}</div>
</template>
<script>
export default {
data(){
return {
text: '',
show: true
};
}
};
</script>
下面是插件的逻辑 toast.js
import Vue from 'vue';
import toastComponent from './toast.vue';
const ToastConstruction = Vue.extend(toastComponent); // 创建Vue子类
function showToast (text, duration = 2000) {
const toast = new ToastConstruction();
let el = toast.$mount().$el; // 挂载实例,获取实例DOM元素
document.body.appendChild(el); // 将toast实例DOM元素添加到文档中
setTimeout(() => {
document.body.removeChild(el);
}, duration);
}
function registryToast() {
// 添加实例方法
Vue.prototype.$toast = showToast;
// 添加全局方法
Vue.$toast = showToast;
// 添加全局mixin
Vue.mixin({
methods: {
toast: showToast
}
});
// 添加全局指令
Vue.directive('show-toast', {
bind(el, binding, vnode){
el.addEventListener('click', function (e) {
showToast(binding.value);
});
}
});
}
export default registryToast;
这样,一个简单的toast插件就做好了!
使用方法
全局入口文件 main.js
...
import Vue from 'vue';
import myToast from './plugin/toast';
Vue.use(myToast); // 相当于调用插件的 install 方法(如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。)
...
需要调用toast的页面 page/page.vue
<template>
...
<p @click="testGlobal">全局方法</p>
<p @click="testPrototype">实例方法</p>
<p @click="testMixin">mixin</p>
<p v-show-toast="'指令'">指令</p> // 使用指令触发
...
</template>
<script>
import Vue from 'vue';
...
methods: {
testGlobal(){
Vue.$toast('Global'); // 全局方法
},
testMixin(){
this.toast('Mixin'); // 利用mixin注入方法
},
testPrototype(){
this.$toast('Prototype'); // 利用prototype添加实例方法
}
}
...
</script>