You need to enable JavaScript to run this app. 如何基于Vue3 Composition API开发确认弹窗、Toast类支持组件渲染的插件
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Vue3 Composition API开发确认弹窗、Toast类支持组件渲染的插件

Vue3 确认弹窗插件实现方案

核心基于Vue3内置的createVNode和renderAPI实现动态组件渲染、状态传递和实例销毁,完全符合你预期的调用方式。

1. 完善入口文件 index.js

import { createVNode, render } from 'vue'
import Component from './component';

export default {
    install(app, options = {}) {
        // 全局默认配置,可在注册插件时自定义覆盖
        const defaultConfig = {
            title: '系统提示',
            description: '是否确认执行该操作?',
            ...options
        }

        const handler = function(userOptions) {
            // 合并全局配置与单次调用的自定义配置
            const finalOptions = { ...defaultConfig, ...userOptions }
            
            return new Promise((resolve) => {
                // 创建临时DOM容器存放弹窗实例
                const container = document.createElement('div')

                // 生成组件虚拟节点,传入参数、resolve方法、关闭回调
                const vnode = createVNode(Component, {
                    title: finalOptions.title,
                    description: finalOptions.description,
                    resolve,
                    // 组件关闭时触发的销毁逻辑
                    onClose: () => {
                        // 清空容器渲染内容
                        render(null, container)
                        // 移除DOM节点,完成实例销毁
                        document.body.removeChild(container)
                    }
                })

                // 绑定当前应用上下文,确保组件可正常使用全局注册的组件、插件等能力
                vnode.appContext = app._instance.appContext

                // 渲染组件到容器,再挂载到body节点
                render(vnode, container)
                document.body.appendChild(container)
            });
        };

        // 注册为注入项,供Composition API组件通过inject调用
        app.provide('confirm', handler);
        // 可选:注册为全局方法,供选项式API组件通过this.$confirm调用
        app.config.globalProperties.$confirm = handler
    },
};

2. 完善弹窗组件 component.vue

仅需新增关闭事件触发逻辑,其余原有代码保持不变即可:

<template>
  <!-- 外层包裹你引入的Modal组件,确保弹窗层级、显隐逻辑正常 -->
  <Modal :visible="true" append-to-body>
    <div class="modal-title">{{ title }}</div>
    <div class="modal-body">{{ description }}</div>
    <div class="modal-footer">
        <Button @click="handleConfirm">Confirm</Button>
        <Button @click="handleReject">Reject</Button>
        <Button @click="handleClose">Close</Button>
    </div>
  </Modal>
</template>

<script>
import { Modal, Button } from '你的UI库路径'
export default {
    name: 'Confirm',
    components: {
        Modal,
        Button,
    },
    // 声明关闭事件
    emits: ['close'],
    props: {
        title: {
            type: String,
            default: '',
        },
        description: {
            type: String,
            default: '',
        },
        resolve: {
            type: Function,
        },
    },
    setup(props, { emit }) {
        function handleClose() {
            props.resolve(null);
            // 触发关闭事件,通知入口文件销毁实例
            emit('close');
        }

        function handleConfirm() {
            props.resolve(true);
            emit('close');
        }

        function handleReject() {
            props.resolve(false);
            emit('close');
        }

        return {
            handleClose,
            handleConfirm,
            handleReject,
        };
    },
};
</script>

可选优化方案

  • 可新增自定义按钮文字、弹窗宽度、是否显示关闭按钮等配置项,扩展插件能力
  • 如果需要支持关闭动画,可以给组件新增visible响应式变量,点击按钮时先修改visible为false,等动画结束后再触发emit('close')销毁实例
  • 可增加重复调用拦截逻辑,避免同时弹出多个确认弹窗

内容的提问来源于stack exchange,提问作者Jlblcblu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 15:24:02