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