LZM

分享vue3自定义message消息组件

2024-10-30 16:02:30

在目录components中创建文件Message.vue, 内容如下:

Vue 复制代码
<script setup>
const props = defineProps({
    message: String,
    duration: {
        type: Number,
        default: 3000,
    },
    type: {
        type: String,
        default: "none",
    },
});

const visible = ref(false);
const showMessage = () => {
    visible.value = true;
    setTimeout(() => {
        visible.value = false;
    }, props.duration);
};

onMounted(() => {
    showMessage();
});
</script>
<template>
    <transition name="fade">
        <div v-if="visible" class="fixed top-10 left-[50%] translate-x-[-50%] rounded p-4 bg-slate-600/50 text-white z-50 inline-flex items-center gap-x-2">
            <Suspense>
                <Icon v-if="type == 'success'" name="ep:success-filled" size="20" class="text-[#a3e635]" />
                <Icon v-else-if="type == 'error'" name="ep:warning" size="20" class="text-[#ef4444]" />
            </Suspense>
            <p>{{ message }}</p>
        </div>
    </transition>
</template>

<style scoped>
.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.5s;
}
.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
</style>

在目录composables中创建文件useMessage.js, 内容如下:

Javascript 复制代码
import { createApp, h } from "vue";
import Message from "~/components/Message.vue";

export function Mymessage(message, duration = 3000, type = "none") {
    const app = createApp({
        render() {
            return h(Message, { message, duration, type });
        },
    });

    const container = document.createElement("div");
    document.body.appendChild(container);
    app.mount(container);

    setTimeout(() => {
        app.unmount();
        document.body.removeChild(container);
    }, duration + 500); // 给过渡动画预留时间
}

在页面中调用:

vue 复制代码
<template> 
  <div> <button @click="showMessage">显示消息</button> </div>
</template> 
<script setup> 
  const showMessage = () => {
    Mymessage("这是一个测试消息");
  }
</script>
End