123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import { Component, ref, shallowRef } from "vue";
- import XEUtils from "xe-utils";
- interface DialogProps {
- title: string;
- fullscreen?: boolean;
- width?: number | string;
- top?: string | number;
- showClose?: boolean;
- alignCenter?: boolean;
- closeOnClickModal?: boolean;
- closeOnPressEscape?: boolean;
- }
- export type CloseValue = "close" | "confirm" | "cancel";
- export interface DialogExpose {
- // 如果报错了会阻止关闭弹窗
- confirm: () => any | Promise<any>;
- // 如果报错了会阻止关闭弹窗
- cancel: () => any | Promise<any>;
- }
- export namespace UseDialogType {
- export interface Expose extends DialogExpose {}
- export interface Emits {
- (e: "cyDialogConfirm" | "cyDialogCancel", value?: any): void;
- }
- }
- type FirstParam<T> =
- T extends Component<infer P, any, any, any, any, any>
- ? P extends Record<string, any>
- ? P
- : {}
- : never;
- export interface DialogOptions<P = Component> {
- dialogProps: DialogProps;
- params?: any;
- showCancel?: boolean;
- hideHeader?: boolean;
- showConfirm?: boolean;
- showFooter?: boolean;
- cancelText?: string;
- confirmText?: string;
- visible?: boolean;
- component?: any;
- componentRef?: DialogExpose;
- manuallyClose?: (
- cb: (value: CloseValue, data: any) => void,
- currentItem: DialogState
- ) => void;
- }
- export interface DialogState extends DialogOptions {
- resolve: (val: { value: CloseValue; data: any }) => void;
- reject: (val: { value: CloseValue; data: any }) => void;
- dialogKey?: number;
- closeValue?: CloseValue;
- }
- export const dialogStore = ref<DialogState[]>([]);
- export const dialogKey = ref(1);
- export function useDialog<R = any, C = Component>(
- component: C,
- props: DialogOptions<C>
- ) {
- return new Promise<R>((resolve, reject) => {
- props = {
- visible: true,
- component: shallowRef(component),
- showCancel: true,
- showConfirm: true,
- showFooter: true,
- hideHeader: false,
- ...props,
- };
- dialogKey.value++;
- const pushIndex = dialogStore.value.push({
- ...props,
- resolve: XEUtils.once(value => {
- resolve(value);
- }),
- reject: XEUtils.once(value => {
- reject(value);
- }),
- dialogKey: dialogKey.value,
- closeValue: "close",
- });
- if (props.manuallyClose) {
- const currentItem = dialogStore.value[pushIndex - 1];
- currentItem.dialogProps.showClose = false;
- currentItem.dialogProps.alignCenter =
- currentItem.dialogProps.alignCenter ?? true;
- currentItem.dialogProps.closeOnClickModal = false;
- currentItem.dialogProps.closeOnPressEscape = false;
- currentItem.showFooter = false;
- props.manuallyClose(
- (value: CloseValue, data: any) => {
- const item = dialogStore.value[pushIndex - 1];
- if (value === "confirm") {
- item.resolve(data);
- } else {
- item.reject({ value: item.closeValue, data });
- }
- item.visible = false;
- },
- dialogStore.value[pushIndex - 1]
- );
- }
- });
- }
- export const dialogKeyType: InjectionKey<DialogState> = Symbol("cyDialog");
|