美文网首页Vue
编写vue插件入门【详细讲解】

编写vue插件入门【详细讲解】

作者: _littleTank_ | 来源:发表于2018-01-19 13:52 被阅读0次

    前言:

    现在随着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()调用
    

    到此完结。

    相关文章

      网友评论

        本文标题:编写vue插件入门【详细讲解】

        本文链接:https://www.haomeiwen.com/subject/eyrooxtx.html