123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- import type { ModalApiOptions, ModalState } from './modal';
- import { Store } from '@vben-core/shared/store';
- import { bindMethods, isFunction } from '@vben-core/shared/utils';
- export class ModalApi {
- // 共享数据
- public sharedData: Record<'payload', any> = {
- payload: {},
- };
- public store: Store<ModalState>;
- private api: Pick<
- ModalApiOptions,
- | 'onBeforeClose'
- | 'onCancel'
- | 'onClosed'
- | 'onConfirm'
- | 'onOpenChange'
- | 'onOpened'
- >;
- // private prevState!: ModalState;
- private state!: ModalState;
- constructor(options: ModalApiOptions = {}) {
- const {
- connectedComponent: _,
- onBeforeClose,
- onCancel,
- onClosed,
- onConfirm,
- onOpenChange,
- onOpened,
- ...storeState
- } = options;
- const defaultState: ModalState = {
- bordered: true,
- centered: false,
- class: '',
- closeOnClickModal: true,
- closeOnPressEscape: true,
- confirmDisabled: false,
- confirmLoading: false,
- contentClass: '',
- destroyOnClose: true,
- draggable: false,
- footer: true,
- footerClass: '',
- fullscreen: false,
- fullscreenButton: true,
- header: true,
- headerClass: '',
- isOpen: false,
- loading: false,
- modal: true,
- openAutoFocus: false,
- showCancelButton: true,
- showConfirmButton: true,
- title: '',
- animationType: 'slide',
- };
- this.store = new Store<ModalState>(
- {
- ...defaultState,
- ...storeState,
- },
- {
- onUpdate: () => {
- const state = this.store.state;
- // 每次更新状态时,都会调用 onOpenChange 回调函数
- if (state?.isOpen === this.state?.isOpen) {
- this.state = state;
- } else {
- this.state = state;
- this.api.onOpenChange?.(!!state?.isOpen);
- }
- },
- },
- );
- this.state = this.store.state;
- this.api = {
- onBeforeClose,
- onCancel,
- onClosed,
- onConfirm,
- onOpenChange,
- onOpened,
- };
- bindMethods(this);
- }
- /**
- * 关闭弹窗
- * @description 关闭弹窗时会调用 onBeforeClose 钩子函数,如果 onBeforeClose 返回 false,则不关闭弹窗
- */
- async close() {
- // 通过 onBeforeClose 钩子函数来判断是否允许关闭弹窗
- // 如果 onBeforeClose 返回 false,则不关闭弹窗
- const allowClose = (await this.api.onBeforeClose?.()) ?? true;
- if (allowClose) {
- this.store.setState((prev) => ({
- ...prev,
- isOpen: false,
- }));
- }
- }
- getData<T extends object = Record<string, any>>() {
- return (this.sharedData?.payload ?? {}) as T;
- }
- /**
- * 锁定弹窗状态(用于提交过程中的等待状态)
- * @description 锁定状态将禁用默认的取消按钮,使用spinner覆盖弹窗内容,隐藏关闭按钮,阻止手动关闭弹窗,将默认的提交按钮标记为loading状态
- * @param isLocked 是否锁定
- */
- lock(isLocked = true) {
- return this.setState({ submitting: isLocked });
- }
- /**
- * 取消操作
- */
- onCancel() {
- if (this.api.onCancel) {
- this.api.onCancel?.();
- } else {
- this.close();
- }
- }
- /**
- * 弹窗关闭动画播放完毕后的回调
- */
- onClosed() {
- if (!this.state.isOpen) {
- this.api.onClosed?.();
- }
- }
- /**
- * 确认操作
- */
- onConfirm() {
- this.api.onConfirm?.();
- }
- /**
- * 弹窗打开动画播放完毕后的回调
- */
- onOpened() {
- if (this.state.isOpen) {
- this.api.onOpened?.();
- }
- }
- open() {
- this.store.setState((prev) => ({
- ...prev,
- isOpen: true,
- submitting: false,
- }));
- }
- setData<T>(payload: T) {
- this.sharedData.payload = payload;
- return this;
- }
- setState(
- stateOrFn:
- | ((prev: ModalState) => Partial<ModalState>)
- | Partial<ModalState>,
- ) {
- if (isFunction(stateOrFn)) {
- this.store.setState(stateOrFn);
- } else {
- this.store.setState((prev) => ({ ...prev, ...stateOrFn }));
- }
- return this;
- }
- /**
- * 解除弹窗的锁定状态
- * @description 解除由lock方法设置的锁定状态,是lock(false)的别名
- */
- unlock() {
- return this.lock(false);
- }
- }
|