/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable no-unused-vars */ import Vue, { CreateElement, VNode } from 'vue'; import { QXEvent } from 'qx-util'; import { IOverlayContainer } from '@ibiz-template/runtime'; import router from '@/router'; import { piniaInstance } from '@/store'; /** * 全局弹出承载组件 * * @author chitanda * @date 2022-11-09 12:11:09 * @export * @class OverlayContainer */ export class OverlayContainer<O> implements IOverlayContainer { /** * vue 飘窗呈现实例 * * @author chitanda * @date 2022-11-09 12:11:09 * @protected * @type {Vue} */ protected vm?: Vue; /** * 具体模态组件 * * @author chitanda * @date 2022-11-09 12:11:34 * @protected * @type {*} */ protected modal: any; /** * 外面调用dismiss时传的result结果 * * @author lxm * @date 2022-11-09 20:11:06 * @protected * @type {unknown} */ protected result?: unknown; /** * 内部事件 * * @author chitanda * @date 2022-11-09 12:11:42 * @protected */ protected evt: QXEvent<{ dismiss: (data?: unknown) => void }> = new QXEvent(); /** * 创建全局呈现 * * @author chitanda * @date 2022-11-09 14:11:52 * @param {unknown} component * @param {(h: CreateElement) => VNode} render * @param {IPopoverOptions} [opts] */ constructor( protected component: unknown, protected render: (h: CreateElement) => VNode, protected opts?: O, ) { this.init(); } /** * 初始化飘窗 * * @author chitanda * @date 2022-11-09 12:11:55 * @protected * @return {*} {void} */ protected init(): void { const self = this; const { render, opts } = this; const container = document.createElement('div'); document.body.appendChild(container); const vm = new Vue({ el: container, pinia: piniaInstance, router, beforeDestroy() { vm!.$el.remove(); }, mounted() { self.modal = this.$refs.root; }, destroyed() { self.evt.emit('dismiss', self.result); }, render(h) { return h( self.component as string, { ref: 'root', props: { opts }, on: { dismiss() { vm!.$destroy(); }, }, }, [render(h)], ); }, }); this.vm = vm; } /** * 打开飘窗 * * @author chitanda * @date 2022-11-09 12:11:52 * @param {HTMLElement} target * @return {*} {Promise<void>} */ async present(): Promise<void> { return this.modal.present(); } /** * 手动调用关闭飘窗 * * @author chitanda * @date 2022-11-09 12:11:39 * @param {unknown} [data] * @return {*} {Promise<void>} */ async dismiss(data?: unknown): Promise<void> { this.result = data; this.modal.dismiss(); } /** * 订阅窗口关闭 * * @author chitanda * @date 2022-11-09 12:11:20 * @template T * @return {*} {Promise<T>} */ async onWillDismiss<T = unknown>(): Promise<T> { return new Promise<T>(resolve => { const callback = (data: unknown) => { resolve(data as T); this.evt.off('dismiss', callback); }; this.evt.on('dismiss', callback); }); } }