其实我们已经用过的很多插件如:axios,vue-router等都是自定义的插件,然后被开发者普遍运用被熟知。这些插件中也可以分为两类:1.基于Vue.js基础开发的插件;2.其他插件(非Vue.js语法),而我们自己开发的插件属于第一类,基于Vue.js开发。
根据官网的定义,Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器 , 第二个参数是一个可选的选项对象:
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) {
// 逻辑...
}
}
本人在学习和查阅相关资料的过程中,总结出两种不同的实现方式:1.明确暴露install方法开发的自定义插件;2.直接引用Vue开发的自定义插件。
在项目目录下新建组件MyToast.vue并且定义好toast的样式,并且用两张png做不同参数的显示,当传入参数为’S’和‘F’时显示不同图片,css样式使用less格式,需要安装和导入less和less-loader第三方插件:
{{ msg }}
//引入写好的MyToast.vue组件
import MyToast from './MyToast.vue'
//声明一个变量用来存放构造器
let $vm
export default{
//调用暴露的install函数 ----------注意:此处的Vue是一个传入的形参,与第二中方法中要区分----------
install(Vue){
//变量为空执行
if(!$vm){
//调用Vue的extend方法生成一个构造器myToastConstructor继承MyToast
const myToastConstructor = Vue.extend(MyToast);
//构造器实例化
$vm = new myToastConstructor({
//在构造器内部调用document生成一个div元素用来存放MyToast.vue中写好的模板template
el: document.createElement('div')
});
//调用document将构造器和生成的div元素添加到DOM中使其能够被渲染
document.body.appendChild($vm.$el);
}
//首先赋值MyToast.vue中的,也就是构造器继承的是否显示toast组件的字段isShowToast 为false
$vm.isShowToast = false;
//声明toast并为其声明两个方法,显示和隐藏toast
let toast = {
//show方法传入两个参数分别为显示成功或者失败,显示的信息(与MyToast.vue中的数据对应)
show(showType, msg){
$vm.isShowToast = true;
$vm.showType = showType;
$vm.msg = msg
},
//定义隐藏toast的方法
hide(){
$vm.isShowToast = false;
}
};
//判断Vue中是否有toast属性,没有就将上面定义好的toast赋值给Vue的属性
if(!Vue.toast){
Vue.$toast = toast;
}
//通过调用添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现全局注册
Vue.prototype.$toast = Vue.$toast
}
}
在main.js中引入上面写好的js文件,并注册到Vue中:
import toast from './plugins/myToast/index.js'
Vue.use(toast)
在Vue项目的任何组件中可以调用定义好的组件toast:
//假如在某个组件的mounted生命周期函数中调用
mounted(){
//通过this.$toast.show掺入参数调用显示函数
this.$toast.show('S','成功')
//设置计时器2秒中后调用this.$toast.hide()隐藏toast
setTimeout(() => {
this.$toast.hide()
}, 2000);
}
切换到订单后在其mounted中执行toast并且2秒后自动隐藏。
在项目目录下新建组件MyToast.vue并且定义好toast的样式,同样用两张png做不同参数的显示(图片与二中不一样哟,做一个小小的区分),当传入参数type为’S’和‘F’时显示不同图片,css样式使用less格式,需要安装和导入less和less-loader第三方插件:
{{msg}}
//------注意:此处导入了Vue组件,与第一种方法中的形参Vue要区分-------
import Vue from 'vue'
//引入写好的MyToast.vue组件
import ToastComponent from './MyToast.vue'
//定义构造器继承导入的ToastComponent
const toastConstructor = Vue.extend(ToastComponent)
//定义方法showToast
function showToast(text, t, duration=2000){
//在方法中实例化构造器定添加div元素和对ToastComponent的数据进行赋值
const toastDom = new toastConstructor({
el: document.createElement('div'),
data(){
return{
msg: text,
isShow: true,
type: t
}
}
})
//将构造器添加的元素放入DOM中使其能够被渲染
document.body.appendChild(toastDom.$el)
//方法中设置定时器2秒后重新赋值sShow为false达到关闭toast的效果
setTimeout(() => {
toastDom.isShow =false
}, duration);
}
//定义注册方法registryToast,通过把它们添加到 Vue.prototype 上实现全局注册
function registryToast(){
Vue.prototype.$toast = showToast
}
//最后将注册方法作为导出项
export default registryToast
在main.js中引入上面写好的js文件,并注册到Vue中:
import toastPlugin from './plugins/MyToast/index.js'
Vue.use(toastPlugin)
在Vue项目的任何组件中可以调用定义好的组件toast:
在组件的template中定义一个按钮元素:
显示Toast
对按钮事件进行完善:
methods:{
/**显示全局的Toast自定义组件 */
showToast(){
this.$toast("显示成功", 'S')
}
},
上诉的两种方是大家开发插件时所用到的,现在网上的博客和资料中也都是这两种方法及一些微小的变形,但是对于两种方法的区分和详细说明并没有写道。因此上述两种方法也只是我个人的理解。现在具体说下两种方法的区别:
这与官方文档一致,按照其暴露的install方法,并在install方法中完成组件的封装和注册;其中inastll方法传入两个参数:Vue为必选,options为可选;并且根据方法的了解,Vue为形参。本人试着将install方法改为其他名字,如inst等,其他的不变,再次运行报错:mounted函数中的show方法未定义
说明toast在Vue中找不到,并没有被赋值到Vue.prototype 属性上,所以install可以看作是Vue开发插件注册的默认“入口”,修改名字后Vue就无法识别或者找不到对应的函数,所以install必须给出且插件的封装和注册在其方法中完成!
对于该方法,我们发现并没有使用install方法,但是他却能执行,你说奇怪不奇怪!于是冲代码上面进行分析:在第二和第三部分代码详解时已经有过交代,调用暴露的install函数时“Vue”是一个传入的形参,而此方法中注意是导入了Vue组件import Vue from 'vue'
,与第一种方法中的形参Vue要区分。本人没有看过Vue的源码,所以一不知道个所以然,因此只能猜测在此方法中引入了Vue,vue中已经默认调用了insatll方法,然后在:
function registryToast(){
Vue.prototype.$toast = showToast
}
中将自定义的showToast方法赋值给Vue.prototype.的属性,然后再放入默认调用的Vue的install中!
当然这只是一个猜测,或许上述的两种方法其实就是一种方法,第二种方法是第一种方法的变形形式,希望有大佬能够解释下!
欢迎大家关注本人的微信公众号,微信公众号将不定期发送相应学习文章和教程