kui-dialog-cmd.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import {Component, h, render} from "vue";
  2. import alertModel from "./alertModel.vue"
  3. export enum KuiDialogType {
  4. alert,
  5. confirm,
  6. prompt,
  7. loading,
  8. custom
  9. }
  10. export interface KuiDialogCmdOptions {
  11. dialogType?: KuiDialogType;
  12. showContent: string | Component;
  13. mountTarget?: string;
  14. className?: string;
  15. onClose?: () => void;
  16. beforeClose?: () => boolean;
  17. onOk?: () => void;
  18. on?: Record<string, (...args: any[]) => void>;
  19. }
  20. export class KuiDialogCmd {
  21. static defaultOptions: KuiDialogCmdOptions = {
  22. dialogType: KuiDialogType.custom,
  23. showContent: "kui-dialog",
  24. mountTarget: "kui-root",
  25. beforeClose: (): boolean => {
  26. return true;
  27. },
  28. onClose() {
  29. },
  30. onOk() {
  31. },
  32. className: "kui-dialog",
  33. }
  34. options: KuiDialogCmdOptions;
  35. containerEl: HTMLElement;
  36. targetEl: HTMLElement | null;
  37. showFlag: boolean;
  38. tmpVNode: any;
  39. constructor(opt: KuiDialogCmdOptions) {
  40. this.options = {
  41. ...KuiDialogCmd.defaultOptions,
  42. ...opt
  43. };
  44. this.containerEl = document.createElement('div');
  45. this.containerEl.className = <string>this.options.className;
  46. this.targetEl = null;
  47. this.showFlag = false;
  48. }
  49. show( props?: any ) {
  50. let eventListeners;
  51. if (this.options.dialogType === KuiDialogType.alert) {
  52. eventListeners = {
  53. onOk: () => {
  54. this.hide();
  55. // 阻断hide触发close事件, 用于在外部
  56. this.options.onOk?.();
  57. },
  58. onCancel: () => {
  59. this.hide(true);
  60. },
  61. }
  62. } else {
  63. eventListeners = {
  64. onClose: () => this.hide(true),
  65. };
  66. }
  67. // 解析 option中的on
  68. // 根据参数决定显示类型
  69. let vNode =
  70. h(this.options.showContent, {
  71. ...props,
  72. // 这里会将所有其他事件(包括未明确绑定)传递给子组件
  73. on: {
  74. ...this.options.on, // 传递的自定义事件
  75. ...this.getAllListeners(), // 获取所有未明确定义的事件
  76. },
  77. ...eventListeners,
  78. ...this.options.on
  79. });
  80. render(vNode, this.containerEl);
  81. let target = document.getElementById(<string>this.options.mountTarget);
  82. if (!target) {
  83. target = document.body;
  84. }
  85. target.appendChild(this.containerEl);
  86. this.targetEl = target;
  87. this.showFlag = true;
  88. }
  89. hide(isSub: boolean = false) {
  90. let beforeCloseFn = this.options.beforeClose;
  91. let closeFn = this.options.onClose;
  92. if (beforeCloseFn && !beforeCloseFn()) {
  93. // 被阻止关闭
  94. return;
  95. }
  96. if (this.targetEl) {
  97. this.targetEl.removeChild(this.containerEl);
  98. }
  99. render(null, this.containerEl);
  100. this.showFlag = false;
  101. if (isSub && closeFn) closeFn();
  102. }
  103. getAllListeners() {
  104. // 获取所有从 options.on 传递过来的事件监听器
  105. return this.options.on || {};
  106. }
  107. isShow() {
  108. return this.showFlag;
  109. }
  110. }
  111. export interface KuiDialogAlertOptions{
  112. title: string;
  113. content: string;
  114. okText?: string;
  115. cancelText?: string;
  116. onOk?: () => void;
  117. onCancel?: () => void;
  118. showCancel?: boolean;
  119. }
  120. export function showAlert( alertOptions: KuiDialogAlertOptions, mountTarget: string = "kui-root"): KuiDialogCmd
  121. {
  122. const defaultOptions: KuiDialogAlertOptions = {
  123. title: "提示",
  124. content: "内容",
  125. okText: "确定",
  126. cancelText: "取消",
  127. onOk: () => {},
  128. onCancel: () => {},
  129. showCancel: true,
  130. }
  131. let _alertOptions: KuiDialogAlertOptions = {
  132. ...defaultOptions,
  133. ...alertOptions
  134. }
  135. let dialogOptions: KuiDialogCmdOptions = {
  136. dialogType: KuiDialogType.alert,
  137. showContent: alertModel,
  138. mountTarget: mountTarget,
  139. onOk: _alertOptions.onOk,
  140. onClose: _alertOptions.onCancel,
  141. }
  142. let dialog = new KuiDialogCmd(dialogOptions);
  143. dialog.show({
  144. title: _alertOptions.title,
  145. content: _alertOptions.content,
  146. okText: _alertOptions.okText,
  147. cancelText: _alertOptions.cancelText,
  148. showCancel: _alertOptions.showCancel,
  149. });
  150. return dialog;
  151. }