The directory organization

├ ─ SRC instance.js message.js message.js message.less message.vueCopy the code
  • src/Message.vue
<template>
    <! -- Message list -->
    <transition name="slide-fade">
        <div class="message-container" v-show="visibled">
            <! - content - >
            <div class="message-content">

                <! -- Message type icon, determined by message type, text type is not configured icon -->
                <div class="message-icon" v-if="config.icon">
                    <i :class="config.icon"></i>
                </div>

                <! -- Message text -->
                <span v-text="config.content"></span>

                <! Close the message manually -->
                <div class="option" v-if=! "" config.close">
                    <i class="ri-close-fill" @click="onClose"></i>
                </div>

            </div>
        </div>
    </transition>
</template>
<script>
import {reactive, toRefs} from "vue";

export default {
    props: {
        config: {
            type: Object.default: () = >{}},// Message configuration items
        remove: {
            type: Function.default: () = >{}},// Cancel the mount callback
    },
    setup(props) {
        const state = reactive({
            visibled: false,})// Open the message
        const onOpen = (config) = > {
            setTimeout(() = > {
                state.visibled = true;
            }, 10)

            // Remove the message after the specified time
            if(config.duration ! = =0) {
                setTimeout(() = > {
                    onClose();
                }, config.duration);
            }
        }

        onOpen(props.config)

        // The message is closed
        const onClose = () = > {
            state.visibled = false;
            setTimeout(() = > {
                props.remove()
            }, 200)};return{... toRefs(state), onOpen, onClose, }; }};</script>
<style>
@import "Message.less";
</style>
Copy the code
  • src/Message.less
@radius: 4px;
@normalHeight: 34px;

.message {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  box-sizing: border-box;
  z-index: 9999;
  transform: translateZ(9999px);
  padding-top: 28px;
  transition: top .4s ease;

  .message-container {
    margin-bottom: 14px;

    .message-icon {
      display: inline-block;

      i {
        font-size: 18px;
        font-weight: 400;
        margin-top: -3px;
        margin-right: 6px;
        display: inline-block;
        box-sizing: border-box;
        vertical-align: middle;
      }

      .ri-checkbox-circle-fill {
        color: #58c05b;
      }

      .ri-close-circle-fill {
        color: #fd4f4d;
      }

      .message-content {
        display: inline-block;
        padding: 4px 18px;
        height: @normalHeight;
        text-align: left;
        line-height: @normalHeight;
        font-size: 14px;
        font-weight: 400;
        border-radius: @radius;
        color: # 595959;
        box-shadow: 0 4px 12px rgba(0.0.0.15);
        background: #ffffff;

        .option {
          display: inline-block;
          pointer-events: all;
          margin-left: 18px;

          i {
            font-size: 18px;
            font-weight: 400;
            margin-top: -3px;
            display: inline-block;
            box-sizing: border-box;
            vertical-align: middle;
            cursor: pointer;
            color: #d9d9d9;
            transition: color 0.2 s ease;

            &:hover {
              color: #ff7c75;
              transition: color 0.2 s ease;
            }
          }
        }
      }
    }

    .slide-fade-enter-active {
      transition: all .2s ease-out;
    }

    .slide-fade-leave-active {
      transition: all .2s ease;
    }

    .slide-fade-enter-from..slide-fade-leave-to {
      transform: translateY(-20px);
      opacity: 0; }}}Copy the code
  • src/Message.js
import createInstance from './Instance.js'

/** * Read the configuration and render Message *@param {Object} TypeCfg Type configuration *@param {Object/String} CFG Custom configuration */
function renderMsg(typeCfg = {}, cfg = ' ') {
    // Allows message content to be passed in directly, so determine the type of CFG passed in
    const isContent = typeof cfg === 'string'

    // Integrate custom configurations
    cfg = isContent ? {
        content: cfg
    } : cfg

    const config = Object.assign({}, typeCfg, cfg) // Merge the configuration

    const {
        type = 'text'.// Message type
        content = ' '.// Message content
        duration = 3000.// Automatic shutdown delay
        close = false // Whether to display the close button
    } = config

    // Create an instance
    return createInstance({
        type,
        content,
        duration,
        close
    })
}
export default {
    Plain text message
    text(cfg = "") {
        const textCfg = {
            type: "text".icon: ' '
        }

        return renderMsg(textCfg, cfg);
    },
    // Success prompt
    success(cfg = "") {
        const successCfg = {
            type: "success".icon: 'ri-checkbox-circle-fill'
        }

        return renderMsg(successCfg, cfg);
    },
    // Error message
    error(cfg = "") {
        const errorCfg = {
            type: "error".icon: 'ri-close-circle-fill'
        }

        returnrenderMsg(errorCfg, cfg); }},Copy the code
  • src/Instance.js
import {createApp} from 'vue'
import Message from './Message.vue'

/** * Message instance operation *@param {Object} CFG instance configuration */
const createInstance = cfg= > {
    const config = cfg || {}
    // 1. Create the package container and set the outer Class attribute and message count
    let messageNode = document.createElement('div')
    let attr = document.createAttribute("class")
    attr.value = "message"
    messageNode.setAttributeNode(attr)

    // create an instance and mount it to body
    const app = createApp(Message, {
        config,
        remove() {
            handleRemove()// Remove the element, unmount it from the Dom and remove it after the message is closed}})// Mount the instance and append it to the end of body
    app.vm = app.mount(messageNode)
    document.body.appendChild(messageNode)

    app.close = () = > {
        handleRemove()
    }

    // 3. Implement unmount method and re-count after unmount
    const handleRemove = () = > {
        app.unmount(messageNode)
        document.body.removeChild(messageNode)
        resetMsgTop()
    }

    const resetMsgTop = () = > {
        for (let i = 0; i < messageList.length; i++) {
            messageList[i].style.top = `${i * height}px`}}return app
}
export default createInstance
Copy the code
  • index.js
import Message from './src/Message.js';

export default Message;
Copy the code