前言:
现在随着vue的火热,网上出现了很多优秀的vue插件,功能强大,方便使用。但是我们在使用中是不是总觉得少了点什么?我们只是拿来用,却从来没有认真考虑过别人怎么写的,如何实现的,使用的永远是别人的,自己又如何能进步呢?所以接下来会通过一个简单的 vue-toast 插件,来了解掌握插件的开发和使用。这个例子也是我入门的例子,当然了也是网上找的,中间掺杂着自己的理解,也许有不正确的地方,欢迎指正,共同进步。
认识插件:
Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象options,(请查阅vue插件),如下:
MyPlugin.install = function (Vue, options) {//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) { // 逻辑... } }
接下来要讲到的 vue-toast 插件则是通过添加实例方法实现的(也就是说可以使用其他3个方法也是可以的,看具体情况使用)。我们先来看个小例子。
案例
(1)、先新建个js文件来编写插件:toast.js。
var Toast = {}; Toast.install = function (Vue, options) { let opt = { defaultType:'bottom', // 默认显示位置 duration:'3000' // 持续时间 } for(let property in options){//这里options的值是根据Vue.use()传入的,如果没传,这里options就是undefined opt[property] = options[property]; // 使用 options 的配置 } Vue.prototype.$mytoast = (tips,type) => { if(type){ opt.defaultType = type; // 如果有传type,位置则设为该type } if(document.getElementsByClassName('vue-toast').length){ // 如果toast还在,则不再执行 return; } let toastTpl = Vue.extend({ template: '<div class="vue-toast toast-'+opt.defaultType+'">' + tips + '</div>' }); let tpl = new toastTpl().$mount().$el; document.body.appendChild(tpl); setTimeout(function () { document.body.removeChild(tpl); }, opt.duration) } ['bottom', 'center', 'top'].forEach(type => {//forEach,遍历数组里的值传入回调函数 Vue.prototype.$mytoast[type] = (tips) => {//中括号运算符可以用字符串变量的内容作为属性名。点运算符不能 return Vue.prototype.$mytoast(tips,type) } }) } module.exports = Toast;// export default Toast也是可行的
(2)、在 main.js 中,需要导入 toast.js 并且通过全局方法 Vue.use() 来使用插件:
// main.js import Vue from 'vue'; import Toast from './toast.js'; Vue.use(Toast);
(3)、然后,我们在组件中来获取该插件定义的 $mytoast 属性。
// App.vue export default { mounted(){ this.$mytoast.center('这个是弹窗里的文字'); } }
效果图如下:
Vue.use(Toast).png
讲解:
··· let toastTpl = Vue.extend({ template: '<div class="vue-toast toast-'+opt.defaultType+'">' + tips + '</div>' }); let tpl = new toastTpl().$mount().$el;
1、 vm.$mount()是手动地挂载一个未挂载的实例,参见:vm.$mount
2、el,提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
在实例挂载之后,元素可以用 vm.$el 访问。参见: vm.$el
3、在步骤(2)中,我们通过全局方法 Vue.use(Toast)来使用插件,注意这里我们并没有传入可选的选项对象options,这么引用的话,步骤(1)里的如下代码:
for(let property in options){//这里的options是undefined的,也就是说这个是没有效果的 opt[property] = options[property]; }
如果我们想改变效果应该如下使用:
// main.js import Vue from 'vue'; import Toast from './toast.js'; Vue.use(Toast,{ defaultType:'too', duration:'5000' });
这样就可以改变默认的设置值。
上面的代码已经可以算是一个完整的插件写法了,但是调用起来不是那么方便,只能this.$mytoast.center('这个是弹窗内容');这样调用,如果我们想如下调用:
export default { mounted(){ this.$mytoast('99999999999',{ defaultType:'top', // 默认显示位置 duration:'3000' // 持续时间 }) } }
如何实现呢?那我们的toast.js,代码改写如下:
var Toast = {}; Toast.install = function (Vue) { let opt = { defaultType:'bottom', // 默认显示位置 duration:'3000' // 持续时间 } Vue.prototype.$mytoast = (tips,type) => { if(type){ for(let property in type){ opt[property] = type[property]; // 使用 options 的配置 } } if(document.getElementsByClassName('vue-toast').length){ // 如果toast还在,则不再执行 return; } let toastTpl = Vue.extend({ template: '<div class="vue-toast toast-'+opt.defaultType+'">' + tips + '</div>' }); let tpl = new toastTpl().$mount().$el; document.body.appendChild(tpl); setTimeout(function () { document.body.removeChild(tpl); }, opt.duration) } } module.exports = Toast;
main.js如下
// main.js import Vue from 'vue'; import Toast from './toast.js'; Vue.use(Toast);//这里我们就不传入options可选项了
到此就完结了,自己可以动手敲一敲代码,观察一下有什么区别。
见解:
按照我们上边写的这个方法,主要关注下边这个方法:
Vue.prototype.$mytoast = (tips,type) => { .... 判断,其它逻辑 } 这个方法我们写在toast.js里,然后我们又把toast.js导入到了main.js里, 等于说我们在main.js里注册了一个全局的变量$mytoast,方便我们在后边直接this.$mytoast()调用
到此完结。