/** * @name: useModal * @author: 卜启缘 * @date: 2021/5/7 15:26 * @description:useModal * @update: 2021/5/7 15:26 */ import { defineComponent, reactive, createApp, PropType, getCurrentInstance, ComponentInternalInstance, isVNode } from 'vue' import { ElButton, ElDialog } from 'element-plus' import { isFunction } from '@/visual-editor/utils/is' interface ModalOptions { title?: string footer?: null | (() => JSX.Element) content: ComponentInternalInstance | (() => JSX.Element) onConfirm?: () => void onCancel?: () => void props?: { [propName: string]: any } } const Modal = defineComponent({ props: { options: { type: Object as PropType, default: () => ({}) } }, setup(props) { const instance = getCurrentInstance()! const state = reactive({ options: props.options, visible: true }) const methods = { service: (options: ModalOptions) => { state.options = options methods.show() }, show: () => (state.visible = true), hide: () => (state.visible = false) } const handler = { onConfirm: async () => { await state.options.onConfirm?.() methods.hide() }, onCancel: () => { state.options.onCancel?.() methods.hide() } } Object.assign(instance.proxy, methods) return () => ( {{ default: () => isVNode(state.options.content) ? ( ) : isFunction(state.options.content) ? ( state.options.content() ) : null, footer: () => state.options.footer === null ? null : (
取消 确定
) }}
) } }) export const useModal = (() => { let instance: any return (options: ModalOptions) => { if (instance) { instance.service(options) return instance } const div = document.createElement('div') document.body.appendChild(div) const app = createApp(Modal, { options }) instance = app.mount(div) return instance } })()