【vue3组件封装】Message消息组件

文中涉及的其他组件(SIcon)可在专栏中查询

使用

import { Message } from '@/components'
Message.success("Login successful!")
Message.success("Login successful!",3000) //第二个参数是停留时间 可选

效果

在这里插入图片描述

Types

// 消息样式
type MessageStyle = {
   icon: string;
   color: string;
   backgroundColor: string;
   borderColor: string;
};

type MessageStyleKeys = "info" | "success" | "warn" | "error"; // 支持的类型

export interface IMessageStyle {
   [index in MessageStyleKeys]: MessageStyle;
   [index: string]: MessageStyle;
}

常量

// 停留时间
export const MESSAGE_TIMEOUT: number = 3000;
// message样式
// 这里的icon是自己在iconfont找的,名称与其对应,详细可参考本专栏的“Icon图标组件”文章
export const MESSAGE_STYLE: IMessageStyle = {
   warn: {
      icon: "icon-warn-fill",
      color: "#E6A23C",
      backgroundColor: "#fff7e6",
      borderColor: "#ffe7ba",
   },
   error: {
      icon: "icon-error-fill",
      color: "#F56C6C",
      backgroundColor: "#fff1f0",
      borderColor: "#ffccc7",
   },
   success: {
      icon: "icon-success-fill",
      color: "#67C23A",
      backgroundColor: "#f6ffed",
      borderColor: "#d9f7be",
   },
   info: {
      icon: "icon-info-fill",
      color: "#40a9ff",
      backgroundColor: "#e6f7ff",
      borderColor: "#bae7ff",
   },
};

封装

消息组件:SMessage/SMessage.vue

<template>
    <--!自定义动画-->
    <transition name="fade">
        <div class="s-message" :style="MESSAGE_STYLE[props.type]" v-if="isShow">
            <s-icon :icon="MESSAGE_STYLE[props.type].icon" />
            <span class="text">{{ props.text }}</span>
        </div>
    </transition >
</template>

<script lang="ts" setup>
import { MESSAGE_TIMEOUT, MESSAGE_STYLE } from "@/utils" // 参见上面的常量
import { SIcon } from "@/components"
import { ref, onMounted } from "vue"
const props = defineProps({
  // 消息文本
  text: {
    type: String,
    default: ""
  },
  // 消息类型: "info" | "success" | "warn" | "error"
  type: {
    type: String,
    default: "warn" 
  },
  // 消息停留时间
  timeout: {
    type: Number,
    default: MESSAGE_TIMEOUT
  }
})

// 组件状态
const isShow = ref<boolean>(false)

// 注册定时器控制组件的消失
onMounted(() => {
  isShow.value = true
  setTimeout(() => {
    isShow.value = false
  }, props.timeout)
})
</script>

<style scoped lang="less">
.fade-enter-active{
  animation: fade .5s;
}
.fade-leave-active {
  animation: fade .5s reverse;
}

/* 定义帧动画 */
@keyframes fade {
  0% {
    opacity: 0;
    transform: translateY(-50px);
  }

  100% {
    opacity: 1;
  }
}

.s-message {
    min-width: 300px;
    max-width: 350px;
    padding: 8px @itemSpace;
    position: fixed;
    z-index: 9999;
    left: 50%;
    margin-left: -150px;
    top: 25px;
    border-radius: 4px;
    .text {
        vertical-align: middle;
    }
}
</style>

调用后挂载消息组件:SMessage/index.ts

import { MESSAGE_TIMEOUT } from "@/utils" 
import { createVNode, render } from 'vue'
import SMessage from './SMessage.vue'

const div = document.createElement('div')
// 添加到body上
document.body.appendChild(div)

// 定时器标识
let timer: any = null

const renderMessage = (vnode: any, timeout: number) => {
   render(null, div);// 清空上一个虚拟dom
   render(vnode, div);
   clearTimeout(timer);// 清理上一个定时器
   timer = setTimeout(() => {
      render(null, div);
   }, timeout);
};

// 根据不同的调用创建虚拟dom
export default {
   error: (text: string, timeout: number = MESSAGE_TIMEOUT) => {
      const vnode = createVNode(SMessage, { type: "error", text, timeout });
      renderMessage(vnode, timeout);
   },
   warn: (text: string, timeout: number = MESSAGE_TIMEOUT) => {
      const vnode = createVNode(SMessage, { type: "warn", text, timeout });
      renderMessage(vnode, timeout);
   },
   success: (text: string, timeout: number = MESSAGE_TIMEOUT) => {
      const vnode = createVNode(SMessage, { type: "success", text, timeout });
      renderMessage(vnode, timeout);
   },
   info: (text: string, timeout: number = MESSAGE_TIMEOUT) => {
      const vnode = createVNode(SMessage, { type: "info", text, timeout });
      renderMessage(vnode, timeout);
   },
};


好的,针对您的问题,我可以为您提供一个简单的 Vue3 消息提示组件封装示例。 首先,我们可以创建一个单独的 Message 组件用于显示消息提示,如下所示: ```vue <template> <div class="message" :class="type"> <div class="message-content">{{ message }}</div> <div class="close" @click="close">x</div> </div> </template> <script> import { ref } from 'vue'; export default { props: { type: { type: String, default: 'info' }, message: { type: String, required: true } }, setup(props) { const visible = ref(true); const close = () => { visible.value = false; }; return { visible, close }; } }; </script> <style scoped> .message { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); padding: 10px 20px; border-radius: 4px; color: #fff; font-size: 14px; box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2); transition: opacity 0.3s, height 0.3s; opacity: 1; } .message.info { background-color: #1890ff; } .message.success { background-color: #52c41a; } .message.warning { background-color: #faad14; } .message.error { background-color: #f5222d; } .message-content { display: inline-block; margin-right: 10px; } .close { position: absolute; top: 5px; right: 5px; cursor: pointer; } </style> ``` 接着,我们可以在我们的 Vue3 项目中创建一个全局的消息提示插件,用于方便地调用 Message 组件。在该插件中,我们可以定义不同类型的消息提示方法,如 success、info、warning 和 error,分别对应不同的消息提示样式和内容。 ```javascript import { createApp } from 'vue'; import Message from './Message.vue'; const messagePlugin = { install(app) { app.config.globalProperties.$message = { success(message) { showMessage('success', message); }, info(message) { showMessage('info', message); }, warning(message) { showMessage('warning', message); }, error(message) { showMessage('error', message); } }; } }; function showMessage(type, message) { const messageInstance = createApp(Message, { type, message }); const mountNode = document.createElement('div'); document.body.appendChild(mountNode); messageInstance.mount(mountNode); setTimeout(() => { messageInstance.unmount(); document.body.removeChild(mountNode); }, 3000); } export default messagePlugin; ``` 最后,在我们的 main.js 文件中使用该插件即可: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import messagePlugin from './messagePlugin'; const app = createApp(App); app.use(messagePlugin); app.mount('#app'); ``` 这样,我们就完成了一个简单的 Vue3 消息提示组件封装
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值