如何基于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
相关产品推荐
相关产品推荐

