龙空技术网

web技术分享|基于vue3实现自己的组件库,第一章:Message组件

anyRTC云平台 455

前言:

现时姐妹们对“messageboxjs”都比较关心,姐妹们都需要知道一些“messageboxjs”的相关知识。那么小编在网络上汇集了一些有关“messageboxjs””的相关内容,希望看官们能喜欢,姐妹们快快来学习一下吧!

大家好今天将开始新的系列基于vue3实现自己的组件库,本文默认你会安装和创建vue3项目,如果不会请参考vue官网,废话不多说开始实现本章的目标Message组件;

创建组件库工程目录vair是组件库的名字(名字大家随意)安装项目依赖

npm install less -Dnpm install less-loader -D
template
<template>    <div class='v-message'>        <div v-for='(config, index) in messageList' :key='config.id'         :ref= 'el => { if (el) contentList[index] = el}'        :class='["message-item", config.customClass, config.type, { center: config.center }]'>            <i :class='[config.iconClass, "icon"]'></i>            <p class='content'>{{ config.message }}</p>            <i class='close iconfont icon-guanbi1' @click='close(config)' v-if='config.showClose'></i>        </div>    </div></template>
script
import { ref, defineComponent } from 'vue';export default defineComponent({    name: 'message',    setup () {        // 消息列表        const messageList = ref([]);        // ref列表        const contentList = ref([]);        const message = (options) => {            computedConfig(options);        }        const success = (options) => {            computedConfig(options, 'success');        }        const warning = (options) => {            computedConfig(options, 'warning');        }        const error = (options) => {            computedConfig(options, 'error');        }        const computedConfig = (options, type) => {            var option = options || {};            type && (option.type = type);            const config = {                type: option.type || 'prompt', // 没传消息类型就是默认消息                message: option.message || '',                iconClass: option.iconClass || computedIconClass(type || 'prompt'),                customClass: option.customClass,                duration: option.duration >= 0? option.duration : 3000,                showClose: option.showClose,                center: option.center,                onClose: option.onClose,                id: Math.floor(new Date())            };            messageList.value.push(config);            // 如果延时不等于0,就要设置消失时间            if (config.duration !== 0) {                setTimeout(() => {                    contentList.value[0].className += ' messageHide';                    setTimeout(() => {                        messageList.value.splice(0, 1);                    }, 200);                }, config.duration + messageList.value.length * 100);            }        };        const computedIconClass = (type) => {            switch (type) {                case 'prompt':                    return 'iconfont icon-tishi';                case 'success':                    return 'iconfont icon-success';                case 'warning':                    return 'iconfont icon-jinggao--';                case 'error':                    return 'iconfont icon-cuowu';            }        };        const close = (config) => {            const index = messageList.value.findIndex(item => item.id === config.id);            if (index !== -1) {                contentList.value[index].className += ' messageHide';                setTimeout(() => {                    messageList.value.splice(index, 1);                    config.onClose && config.onClose(config);                }, 200);            }        }        return {            messageList,            contentList,            close,            message,            success,            warning,            error        }    }});
css
<style lang='less' scoped>@import url('../../assets/css/animation.css');.v-message {    position: fixed;    z-index: 99999;    top: 50px;    left: 0;    right: 0;    margin: auto;    width: 380px;    .message-item {        display: flex;        align-items: center;        justify-content: space-between;        margin-bottom: 14px;        box-sizing: border-box;        border-radius: 6px;        padding: 14px;        overflow: hidden;        border: 1px solid transparent;        animation: messageShow .5s;        animation-fill-mode: forwards;        .content {            font-size: 12px;            line-height: 20px;            flex: 1;        }        .close {            cursor: pointer;            &:hover {                color: #6b6b6b;            }        }        i {            font-size: 18px;        }        .icon {            margin-right: 14px;        }    }    .center {        justify-content: center;        .content {            flex: 0 1 auto;        }    }    .messageHide {        animation: messageHide .2s linear;        animation-fill-mode: forwards;    }    .prompt {        border: 1px solid #ebeef5;        background-color: #edf2fc;        .content, i {            color: #909399;        }    }    .success {        background-color: #f0f9eb;        border-color: #e1f3d8;        .content, i {            color: #67C23A;        }    }    .warning {        background-color: #fdf6ec;        border-color: #faecd8;        .content, i {            color: #E6A23C;        }    }    .error {        background-color: #fef0f0;        border-color: #fde2e2;        .content, i {            color: #F56C6C;        }    }}</style>
animation.css这个文件的功能就是定义组件所需的动画
@keyframes messageShow {    0% {        transform: translateY(-50px);        opacity: 0;    }    100% {        transform: translateY(0);        opacity: 1;    }}@keyframes messageHide {    0% {        transform: translateY(0);        opacity: 1;    }    100% {        transform: translateY(-50px);        opacity: 0;    }}
编写message.js
import Message from "./Message.vue";import { createApp } from "vue";const createMessage = function () {    const div = document.createElement("div");    div.id = "v-message";    document.body.appendChild(div);    return createApp(Message).mount("#v-message");};export default createMessage();
编写vair出口 index.js后续这个文件会引入很多组件
// Message 消息提示import Message from './components/Message/message.js';const Vair = function(Vue) {    // Message 消息提示    Vue.config.globalProperties.$message = Message;}export default Vair;
使用组件库在main.js中引入
import { createApp } from 'vue';import App from './App.vue';import Vair from './libs/vair/index.js';const app = createApp(App);app.use(Vair).mount('#app');
App.vue中调用
<template>    <div class='message'>        <p class='button' @click='addMsg("success")'>成功</p>        <p class='button' @click='addMsg("warning")'>警告</p>        <p class='button' @click='addMsg("error")'>错误</p>        <p class='button' @click='addMsg("close")'>可关闭</p>        <p class='button' @click='addMsg("center")'>文字居中</p>    </div></template><script>import { getCurrentInstance, defineComponent } from 'vue';export default defineComponent({    setup () {        const app = getCurrentInstance();        const addMsg = (type) => {            if (type === 'success') {                app.ctx.$message.success({                    message: '这是一条成功消息'                });            }                        if (type === 'warning') {                app.ctx.$message.warning({                    message: '这是一条警告消息'                });            }            if (type === 'error') {                app.ctx.$message.error({                    message: '这是一条错误消息'                });            }            if (type === 'close') {                app.ctx.$message.success({                    message: '这是一条可关闭的消息',                    showClose: true,                    onClose: (config) => {                        console.log(config)                    },                });            }            if (type === 'center') {                app.ctx.$message.success({                    message: '这是一条居中的消息',                    center: true                });            }        };        return {            addMsg        }    }})</script><style lang='less' scoped>.message {    width: 500px;    display: flex;    justify-content: space-between;}.button {    width: 76px;    line-height: 34px;    border-radius: 4px;    color: #fff;    background-color: #1890FF;    text-align: center;    cursor: pointer;    font-size: 12px;}</style>
效果展示

标签: #messageboxjs