Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

👉 Faith will move mountains. Book of the Later Han · Biography of King Jing of Guangling by Fan Ye

preface

With the development of business, functional development has been unable to meet our front-end needs. This chapter mainly takes you to experience how to develop a set of components library that belongs to your own

Usage scenario: the development of internal component library of the company, the development of individual component library, decoupled with the project, the use of the same component in multiple projects, only need to maintain a set of component library

How to encapsulate a Toast component

Component Description:

Realize prompt function.

Effect display:

Functions achieved:

    1. According to a judgment condition or click a button, pop-up box;
    1. You can configure location, type, style name, etc

Use case

1. Easy to use
vm.$toast('Network exception! ')
Copy the code
2. Set options
* message message content * duration Duration, in milliseconds * position Display position: Top, Middle, bottom * className Style name vm.$toast({message: 'Network exception! '.duration: 2000.position: 'middle'.className: 'big'
})
Copy the code
3. Error message
vm.$toast({
    message: 'Verification code error! '.duration: 2000.type: 'error'
})
Copy the code

The specific implementation

The first toast. Vue

<template>
    <transition name="toast-pop">
        <div v-show="visible" class="toast" :class="customClass" @click="handleClose">
            <span class="text">{{message}}</span>
        </div>
    </transition>
</template>

<script>
    export default {
        name: 'Toast'.props: {
            message: String.// Prompt content
            className: { / / the style name
                type: String.default: ' '
            },
            position: { // Position: top, middle, bottom
                type: String.default: 'middle'
            },
            type: { // The warning type can be Normal or error
                type: String.defalut: 'normal'
            }
        },
        data () {
            return {
                // Whether to display
                visible: false}},computed: {
            // Get the style
            customClass () {
                let classes = []
                classes.push('toast-' + this.type)
                switch (this.positon) {
                    case 'top':
                        classes.push('is-placetop')
                        break
                    case 'bottom':
                        classes.push('is-placebottom')
                        break
                    default:
                        classes.push('is-placemiddle')}this.className && classes.push(this.className)
                return classes
            }
        },
        methods: {
            handleClose () {
                this.$emit('close')}}}</script>

<style lang="scss" scoped px2rem="false">
    .toast {
        position: fixed;
        box-sizing: border-box;
        min-width: 200px;
        max-width: 50%;
        max-height: 85%;
        margin-top: 0;
        padding: 18px 30px;
        border-radius: 10px;
        background: rgba(0.0.0.0.7);
        color: #fff;
        text-align: center;
        overflow-y: auto;
        z-index: 2000;
        .text {
            display: block;
            font-size: 16px;
            line-height: 1.5;
            text-align: center;
            word-wrap: break-word; }}.is-placetop {
        top: 50px;
        left: 50%;
        transform: translate(-50%.0);
    }
    .is-placemiddle {
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    .is-placebottom {
        bottom: 50px;
        left: 50%;
        transform: translate(-50%.0);
    }
    .is-placetop.toast-pop-enter-active..is-placetop.toast-pop-leave-active..is-placemiddle.toast-pop-enter-active..is-placemiddle.toast-pop-leave-active {
        transition: opacity .3s linear, margin-top .3s ease;
    }

    .is-placetop.toast-pop-enter..is-placetop.toast-pop-leave-to..is-placemiddle.toast-pop-enter..is-placemiddle.toast-pop-leave-to {
        margin-top: 30px;
        opacity: 0;
    }
    .is-placebottom.toast-pop-enter-active..is-placebottom.toast-pop-leave-active {
        transition: opacity .3s linear, margin-bottom .3s ease;
    }

    .is-placebottom.toast-pop-enter..is-placebottom.toast-pop-leave-to {
        margin-bottom: -30px;
        opacity: 0;
    }
    .toast-error {
        background: rgba(255.102.104.9);
    }
</style>
Copy the code

toastPlugin.js

import Vue from 'vue'
import Toast from './toast.vue'

// toast constructor
const ToastConstructor = Vue.extend({
    extends: Toast
})

// Toast instance pool
let toastPool = []

/** Get a toast instance */
let getInstance = () = > {
    // console.log('toastPool:', toastPool)
    if (toastPool.length > 0) {
        return toastPool.shift()
    }
    return new ToastConstructor({
        el: document.createElement('div')})}/** return the instance to the instance pool */
let returnInstance = instance= > {
    if (instance) {
        toastPool.push(instance)
        // console.log(' Return instance :', instance, toastPool)}}/** Remove the toast DOM node */ from the document
function removeDom (event) {
    if (event.target.parentNode) {
        event.target.parentNode.removeChild(event.target)
    }
}

/ / close
ToastConstructor.prototype.close = function () {
    this.visible = false / / not visible
    this.closed = true // Closed state
    this.$el.addEventListener('transitionend', removeDom) // Remove the DOM node after the animation is complete
    returnInstance(this) // The instance object is returned to the instance pool and the instance can be reused
}

// Display a toast message
export default function (options = {}) {
    // Display time, default 3 seconds
    let duration = options.duration || 3000
    let instance = getInstance()
    // console.log('instance=', instance)
    // Display type
    instance.type = options.type || 'normal'
    // Display the content
    instance.message = typeof options === 'string' ? options : options.message
    // Display position: top, middle, bottom
    instance.position = options.position || 'middle'
    instance.className = options.className || ' '
    // Remove the animation completion event
    instance.$el.removeEventListener('transitionend', removeDom)
    instance.$on('close'.() = > {
        instance.close()
    })
    // console.log('instance.$el=', instance.$el)
    // Add nodes to the document
    document.body.appendChild(instance.$el)
    instance.visible = true
    instance.closed = false

    // Clear the timer
    instance.timer && clearTimeout(instance.timer)
    // Set timer to close toast
    instance.timer = setTimeout(() = > {
        // console.log(' off ', instance)! instance.closed && instance.close() instance.timer =null
    }, duration)
}
Copy the code

main.js

import ToastPlugin from './plugins/toastPlugin.js'

// Toast prompt plugin
Vue.use(ToastPlugin)
Copy the code