封装个全局弹窗

封装了弹窗功能的对象。这个对象提供了一些方法来显示和隐藏弹窗,以及处理弹窗的确认和取消操作。

这个对象的success方法创建了一个新的DOM元素,并使用ReactDOM.render将一个空的

渲染到这个元素上,然后将这个元素添加到文档的body中。

另外,onCancel和onOk方法在调用传入的回调函数之后会移除弹窗。这是一个好的做法,但是你可能也想要在success方法中处理这些回调函数,以便在用户点击确认或取消按钮时可以执行相应的操作。

最后,removeDom方法移除了弹窗的DOM元素。

import React, { useEffect } from 'react';
import './index.scss';
import { createRoot } from 'react-dom/client';

type PopupType = 'success' | 'error' | 'info' | 'warning';

interface PopupOptions {
  title: string;
  tips: string;
  type?: PopupType;
  okText?: string;
  cancelText?: string;
  handleOk?: () => void;
  handleCancel?: () => void;
  // 未来可扩展更多参数
}

const BanAreaPopups = {
  dom: null as HTMLElement | null,
  root: null as ReturnType<typeof createRoot> | null,

  show(options: PopupOptions) {
    this.removeDom();

    this.dom = document.createElement('div');

    const {
      title,
      tips,
      type = 'success',
      okText = '确认',
      cancelText = '取消',
      handleOk,
      handleCancel,
    } = options;

    // 关闭弹窗
    const close = (cb?: () => void) => {
      if (typeof cb === 'function') cb();
      this.removeDom();
    };

    const handleWrapperClick = (e: React.MouseEvent<HTMLDivElement>) => {
      if (e.target === e.currentTarget) close(handleCancel);
    };

    const Modal = () => (
      <div className={`modal-wrapper modal-${type}`} onClick={handleWrapperClick}>
        <div className="modal-content">
          <h1>{title}</h1>
          <p>{tips}</p>
          <div className="modal-btns">
            <button className="modal-btn modal-btn-ok" onClick={() => close(handleOk)}>
              {okText}
            </button>
            <button className="modal-btn modal-btn-cancel" onClick={() => close(handleCancel)}>
              {cancelText}
            </button>
          </div>
        </div>
      </div>
    );

    this.root = createRoot(this.dom);
    this.root.render(<Modal />);
    document.body.appendChild(this.dom);
  },

  success(options: Omit<PopupOptions, 'type'>) {
    this.show({ ...options, type: 'success' });
  },

  error(options: Omit<PopupOptions, 'type'>) {
    this.show({ ...options, type: 'error' });
  },

  info(options: Omit<PopupOptions, 'type'>) {
    this.show({ ...options, type: 'info' });
  },

  warning(options: Omit<PopupOptions, 'type'>) {
    this.show({ ...options, type: 'warning' });
  },

  confirm(options: Omit<PopupOptions, 'type'>): Promise<boolean> {
    return new Promise((resolve) => {
      this.show({
        ...options,
        handleOk: () => resolve(true),
        handleCancel: () => resolve(false),
      });
    });
  },

  removeDom() {
    if (this.dom) {
      this.root?.unmount();
      this.dom.remove();
      this.dom = null;
      this.root = null;
    }
  },
};


export default BanAreaPopups;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值