Vue3 之制作toast插件

一、效果图

二、示例代码

toast.vue

<template>
    <transition name="fade">
        <div v-show="visible" class="my-toast">
            <div class="toast-content">
                <span>{{ message }}</span>
            </div>
        </div>
    </transition>
</template>

<script setup>
    import {
        ref,
        watch
    } from 'vue';
    const props = defineProps({
        message: String,
        show: Boolean
    })
    
    const visible = ref(false);
    
    watch(() => props.show, (newVal) => {
        if(newVal) {
            visible.value = true;
        }else{
            visible.value = false;
        }
    })
</script>

<style scoped>
    .my-toast {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 9999;
        padding: 8px 16px;
        border-radius: 4px;
        background: rgba(0, 0, 0, 0.7);
        color: #fff;
        font-size: 14px;
        line-height: 20px;
        max-width: 80%;
    }

    .toast-content {
        display: flex;
        align-items: center;
        gap: 4px;
    }

    .fade-enter-active,
    .fade-leave-active {
        transition: opacity 0.3s ease;
    }

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

toast.js

import {
    createVNode,
    render
} from 'vue';
import MyToast from './toast.vue';
const toast = {
    install(app) {
        let timer = null;
        const container = document.createElement('div');
        document.body.appendChild(container);

        const showToast = ({
            message = '',
            duration = 2000
        }) => {
            const vnode = createVNode(MyToast, {
                message,
                duration,
            });
            // 渲染到容器
            render(vnode, container);
            vnode.component.props.show = true;
            timer = setTimeout(function() {
                if (document.body.contains(container)) {
                    render(null, container);
                }
                clearTimeout(timer);
                timer = null;
            }, duration);
        }

        // 注册全局方法
        app.config.globalProperties.$toast = showToast;
        app.provide('$toast', showToast);
    }
}

export default toast;

main.js

import { createApp } from 'vue'
import App from './App.vue'
import MyToast from './plugins/toast/toast.js';

const app = createApp(App);
app.use(MyToast);
app.mount('#app');

三、调用

<script setup>
    import {
        ref,
        inject
    } from 'vue'

    const $toast = inject('$toast');

    defineProps({
        msg: String
    })
    const count = ref(0)

    const showToast = () => {
        $toast({
            message: '123'
        })
    }
</script>

 

posted @ 2025-06-24 15:27  样子2018  阅读(25)  评论(0)    收藏  举报