Vue.js plug-in development in detail

Keywords: Vue npm less Attribute

Preface

With the increasing popularity of Vue.js, the related plug-ins of Vue.js have been continuously contributed, countless. For example, the official recommendation of vue-router, vuex, etc., are very good plug-ins. But more of us just stay in the stage of use, less self-development. So the next step is to understand the development and use of plug-ins through a simple vue-toast plug-in.

Recognition plug-in

To develop plug-ins, you need to know what a plug-in looks like first.

The plug-in for Vue.js should have a public method install. The first parameter of this method is the Vue constructor, and the second parameter is an optional option object:

MyPlugin.install = function (Vue, options) {
  Vue.myGlobalMethod = function () {  // 1. Add global methods or attributes, such as: vue-custom-element
    // Logic...
  }
  Vue.directive('my-directive', {  // 2. Adding global resources: instructions/filters/transitions, such as vue-touch
    bind (el, binding, vnode, oldVnode) {
      // Logic...
    }
    ...
  })
  Vue.mixin({
    created: function () {  // 3. Add some component options through the global mixin method, such as: vuex
      // Logic...
    }
    ...
  })
  Vue.prototype.$myMethod = function (options) {  // 4. Add instance methods and implement them by adding them to Vue.prototype
    // Logic...
  }
}

The next vue-toast plug-in is implemented by adding instances. Let's start with a small example. First create a new js file to write the plug-in: toast.js

// toast.js
var Toast = {};
Toast.install = function (Vue, options) {
    Vue.prototype.$msg = 'Hello World';
}
module.exports = Toast;

In main.js, you need to import toast.js and use the plug-in through the global method Vue.use():

// main.js
import Vue from 'vue';
import Toast from './toast.js';
Vue.use(Toast);

Then, we get the $msg attribute defined by the plug-in in the component.

// App.vue
export default {
    mounted(){
        console.log(this.$msg);         // Hello World
    }
}

As you can see, the console successfully printed Hello World. Now that $msg is available, we can implement our vue-toast plug-in.

Developing vue-toast

Requirements: In the component, a prompt is popped up by calling this.$toast('Network request failed'), which is displayed at the bottom by default. You can display it in different places by calling this.$toast.top() or this.$toast.center().

When I pop up a prompt, I can add a div to the body to display the prompt information. In different places, I can locate by adding different class names, so I can start writing.

// toast.js
var Toast = {};
Toast.install = function (Vue, options) {
    Vue.prototype.$toast = (tips) => {
        let toastTpl = Vue.extend({     // 1. Create constructors and define templates for prompts
            template: '<div class="vue-toast">' + tips + '</div>'
        });
        let tpl = new toastTpl().$mount().$el;  // 2. Create an instance and mount it after the document
        document.body.appendChild(tpl);     // 3. Add the created instance to the body
        setTimeout(function () {        // 4. Remove the prompt after 2.5 seconds delay
            document.body.removeChild(tpl);
        }, 2500)
    }
}
module.exports = Toast;

As if it were simple, we implemented this.$toast(), and then showed different locations.

// toast.js
['bottom', 'center', 'top'].forEach(type => {
    Vue.prototype.$toast[type] = (tips) => {
        return Vue.prototype.$toast(tips,type)
    }
})

Here, type is passed to $toast for processing at different locations in the method. It is said above that by adding different class names (toast-bottom, toast-top, toast-center), the $toast method needs minor modifications.

Vue.prototype.$toast = (tips,type) => {     // Add type parameter
    let toastTpl = Vue.extend({             // Template Add Location Class
        template: '<div class="vue-toast toast-'+ type +'">' + tips + '</div>'
    });
    ...
}

It seems almost. But if I want to show it at the top by default, it seems a little redundant to call this.$toast.top() every time. Can I just call this.$toast() where I want it? And I don't want to disappear after 2.5 seconds? Notice the options parameter in Toast.install(Vue,options). We can pass in the parameters we want through the options in Vue.use(). Finally, modify the plug-in as follows:

var Toast = {};
Toast.install = function (Vue, options) {
    let opt = {
        defaultType:'bottom',   // Default Display Location
        duration:'2500'         // Duration
    }
    for(let property in options){
        opt[property] = options[property];  // Configuration using options
    }
    Vue.prototype.$toast = (tips,type) => {
        if(type){
            opt.defaultType = type;         // If there is a transfer type, the location is set to that type
        }
        if(document.getElementsByClassName('vue-toast').length){
            // If toast is still there, it will not be executed
            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 => {
        Vue.prototype.$toast[type] = (tips) => {
            return Vue.prototype.$toast(tips,type)
        }
    })
}
module.exports = Toast;

In this way, a simple vue plug-in is implemented, and can be packaged and released through npm, which can be installed next time with npm install.

Source address: vue-toast

More articles: blog

Posted by hatching on Sun, 14 Jul 2019 16:28:58 -0700