存在缺陷,代码修复中
代码实现
// modal-helper.ts
import type { Component } from 'vue';
import { h, render } from 'vue';
import { useAppStore } from '@/store/modules/app';
/**
* 创建同步模态框
* @param loader 模态框组件加载函数
* @param props 传递给模态框的属性
* @returns Promise<{success: boolean, data?: any}>
*/
export function createSyncModal(
loader: () => Promise<{ default: Component }>,
props: Record<string, any> = {},
) {
return new Promise<{ success: boolean; data?: any }>((resolve) => {
const container = document.createElement('div');
document.body.appendChild(container);
/** 移除模态框 */
const cleanup = () => {
render(null, container);
container.remove();
};
loader().then(({ default: ModalComponent }) => {
// 取消时返回 {success: false}
const handleClose = () => {
cleanup();
resolve({ success: false });
};
// 确认时返回 {success: true, data: result}
const handleOk = (result: any) => {
cleanup();
resolve({ success: true, data: result });
};
// 合并props和事件处理
// 这里只保留了 ok、cancel、update:visible 事件
const mergedProps = {
...props,
visible: true,
onOk: async (...args: any[]) => {
handleOk(args);
},
onCancel: async () => {
handleClose();
},
'onUpdate:visible': (val: boolean) => {
props['onUpdate:visible']?.(val);
if (!val) {
handleClose();
}
},
};
const vnode = h(ModalComponent, mergedProps);
const appStore = useAppStore();
const app = appStore.getApp; // !!!需要在 createApp 处,保存起来 app 实例
// 使用同一个 vue 实例
if (app) {
vnode.appContext = app._context;
}
render(vnode, container);
});
});
}
使用
import { createSyncModal } form 'xx/modal-helper'
const fn = async () => {
/** 一些业务逻辑 */
const { success, data } = await createSyncModal('@/xxx/xx-modal.vue', { /* props */ });
if (!success) return;
/** 一些业务逻辑 */
}