Skip to content

vue笔记(九): message消息提示组件

图片

message消息提示插件

先看下实现后的效果

图片

思路

先写一个message的组件,然后用函数封装一下,函数内容会渲染组件到dom,这样使用时用函数调用即可

自定义参数

message:消息内容

type:消息类别:'base,success,danger三种类型

duration:显示时间

新建message.vue文件

html
<template>
    <Transition name="message">
        <div class="message" v-show="isShow">
            <i class="bi bi-check-circle" v-if="type == 'success'"></i>
            <i class="bi bi-exclamation-circle" v-else></i>
            <span>{{message}}</span>
        </div>
    </Transition>
</template>

<script>
    export default {
        name: 'Message',
        props: {
            message: {
                type: String,
                default: '这是一条信息'
            },
            type: {
                type: String,
                default: 'base'
            },
            duration: {
                type: Number,
                default: 2000,//隐藏时间默认2秒
            }
        },
        data() {
            return {
                isShow: true,//控制显示隐藏
                styles: [
                    {
                        color: '#333333',
                        backColor: '#eeeeee',
                        borColor: '#dddddd'
                    },
                    {
                        color: '#67C23A',
                        backColor: '#d1edc4',
                        borColor: '#b3e19d'
                    },
                    {
                        color: '#F56C6C',
                        backColor: '#fef0f0',
                        borColor: '#fde2e2'
                    },
                ],
                currentStyle: {},
            }
        },
        mounted(){
            this.init();
        },
        methods: {
            init(){
                if(this.type == 'base'){
                    this.currentStyle = this.styles[0];
                }
                if(this.type == 'success'){
                    this.currentStyle = this.styles[1]
                }
                 if(this.type == 'danger'){
                    this.currentStyle = this.styles[2]
                }
                setTimeout(()=>{
                    this.isShow = false;
                },this.duration)
            }
        }

    }
</script>

<style scoped>
    .message{
        position: absolute;
        top: 20px;
        left: 50%;
        transform: translateX(-50%);
        padding: 12px 20px;
        background: v-bind(currentStyle.backColor);
        color: v-bind(currentStyle.color);
        border: 1px v-bind(currentStyle.borColor) solid;
        border-radius: 5px;
        font-size: 14px;
        z-index: 99999;
        max-width: 200px;
        box-sizing: border-box;
    }
    .message i{
        margin-right: 10px;
    }
    .message-enter-active,
    .message-leave-active {
        transition: opacity .3s linear;
    }

    .message-enter-from,
    .message-leave-to {
        opacity: 0;
    }
</style>
<template>
    <Transition name="message">
        <div class="message" v-show="isShow">
            <i class="bi bi-check-circle" v-if="type == 'success'"></i>
            <i class="bi bi-exclamation-circle" v-else></i>
            <span>{{message}}</span>
        </div>
    </Transition>
</template>

<script>
    export default {
        name: 'Message',
        props: {
            message: {
                type: String,
                default: '这是一条信息'
            },
            type: {
                type: String,
                default: 'base'
            },
            duration: {
                type: Number,
                default: 2000,//隐藏时间默认2秒
            }
        },
        data() {
            return {
                isShow: true,//控制显示隐藏
                styles: [
                    {
                        color: '#333333',
                        backColor: '#eeeeee',
                        borColor: '#dddddd'
                    },
                    {
                        color: '#67C23A',
                        backColor: '#d1edc4',
                        borColor: '#b3e19d'
                    },
                    {
                        color: '#F56C6C',
                        backColor: '#fef0f0',
                        borColor: '#fde2e2'
                    },
                ],
                currentStyle: {},
            }
        },
        mounted(){
            this.init();
        },
        methods: {
            init(){
                if(this.type == 'base'){
                    this.currentStyle = this.styles[0];
                }
                if(this.type == 'success'){
                    this.currentStyle = this.styles[1]
                }
                 if(this.type == 'danger'){
                    this.currentStyle = this.styles[2]
                }
                setTimeout(()=>{
                    this.isShow = false;
                },this.duration)
            }
        }

    }
</script>

<style scoped>
    .message{
        position: absolute;
        top: 20px;
        left: 50%;
        transform: translateX(-50%);
        padding: 12px 20px;
        background: v-bind(currentStyle.backColor);
        color: v-bind(currentStyle.color);
        border: 1px v-bind(currentStyle.borColor) solid;
        border-radius: 5px;
        font-size: 14px;
        z-index: 99999;
        max-width: 200px;
        box-sizing: border-box;
    }
    .message i{
        margin-right: 10px;
    }
    .message-enter-active,
    .message-leave-active {
        transition: opacity .3s linear;
    }

    .message-enter-from,
    .message-leave-to {
        opacity: 0;
    }
</style>

增加了显示隐藏的动态过渡效果

另外配置不同type下的颜色和对应的icon,根据传入的值动态配置css样式,最后定时显示时间

js
mounted(){
    this.init();
},
methods: {
    init(){
        if(this.type == 'base'){
            this.currentStyle = this.styles[0];
        }
        if(this.type == 'success'){
            this.currentStyle = this.styles[1]
        }
         if(this.type == 'danger'){
            this.currentStyle = this.styles[2]
        }
        setTimeout(()=>{
            this.isShow = false;
        },this.duration)
    }
}
mounted(){
    this.init();
},
methods: {
    init(){
        if(this.type == 'base'){
            this.currentStyle = this.styles[0];
        }
        if(this.type == 'success'){
            this.currentStyle = this.styles[1]
        }
         if(this.type == 'danger'){
            this.currentStyle = this.styles[2]
        }
        setTimeout(()=>{
            this.isShow = false;
        },this.duration)
    }
}

然后新建message.js文件,封装渲染组件挂载到Dom上,以备调用

js
// 引入创建虚拟节点和渲染方法
import { createVNode, render } from "vue";
import messBox from "../components/message.vue";

// 定时器标识
let time = null;

// options是调用时后面跟的参数,组件里props的值
export default (options) => {
        let option = options || {};
        // 检测参数是否是object类型,如果不是抛出错误,终止程序运行。
        if(typeof option != 'object'){
            throw 'ERROR: Message methods Parameter is not an object ; 报错:Message方法参数不是对象';
            return false;
        }
        // 这里duration给一个默认值,是用来清除创建的div容器
        let duration = option.duration || 2000;
         // 调用创建虚拟节点方法
        //  第一个参数为要创建的虚拟节点即编写好的vue组件
        //  第二个参数为props的参数
        const vnode = createVNode(messBox,{...option});
        //  调用渲染方法:将虚拟节点渲染到dom中
        render(vnode, document.body);

        // 如果已经有定时器先清理一遍
        clearTimeout(time);

        // 清理div容器
        time = setTimeout(() => {
            render(null,document.body)
            //加300毫秒是因为元素隐藏的动画时间是300毫秒
        },duration + 300)
   
};
// 引入创建虚拟节点和渲染方法
import { createVNode, render } from "vue";
import messBox from "../components/message.vue";

// 定时器标识
let time = null;

// options是调用时后面跟的参数,组件里props的值
export default (options) => {
        let option = options || {};
        // 检测参数是否是object类型,如果不是抛出错误,终止程序运行。
        if(typeof option != 'object'){
            throw 'ERROR: Message methods Parameter is not an object ; 报错:Message方法参数不是对象';
            return false;
        }
        // 这里duration给一个默认值,是用来清除创建的div容器
        let duration = option.duration || 2000;
         // 调用创建虚拟节点方法
        //  第一个参数为要创建的虚拟节点即编写好的vue组件
        //  第二个参数为props的参数
        const vnode = createVNode(messBox,{...option});
        //  调用渲染方法:将虚拟节点渲染到dom中
        render(vnode, document.body);

        // 如果已经有定时器先清理一遍
        clearTimeout(time);

        // 清理div容器
        time = setTimeout(() => {
            render(null,document.body)
            //加300毫秒是因为元素隐藏的动画时间是300毫秒
        },duration + 300)
   
};

调用

js
import Message from '../plugin/js/message.js'
事件里直接调用

onMessage(){
    Message();
},
换个类型调用

onMessage(){
    Message({
        type:'success',
        message: '这是一条成功的消息'
    })
}
import Message from '../plugin/js/message.js'
事件里直接调用

onMessage(){
    Message();
},
换个类型调用

onMessage(){
    Message({
        type:'success',
        message: '这是一条成功的消息'
    })
}

运行结果

图片

默认显示时间是2秒,自己如果有需要,自定义时间长度

本文到此结束

反馈信息

INFO

邮箱: open_teams@163.com