文章目录
- 前言
- Modal模态框组件
- 1. 功能分析
- 2. 代码+详细注释说明
- 3. 使用方式
- 4. 效果展示
- 总结
前言
今天这篇主要讲项目中经常会用到的模态框Modal组件封装。模态框可用在很多地方,比如弹窗Dialog使用、消息提示Message使用等都可以在外层套上Modal组件,下一讲会讲到Dialog组件的封装,就是基于模态框进行开发的。
Modal模态框组件
1. 功能分析
(1)用于在页面上显示一个弹出窗口,由遮罩层和主体部分组成。遮罩层覆盖整个屏幕,用于阻止点击穿透到下层内容。主体部分包含传入的 children,即模态框的内容。
(2)组件使用 useEffect 钩子来监听 Esc 键的按下,并在按下时关闭模态框
(3)OutsideClickHandler 组件用于检测模态框外部的点击,并调用 onClose 回调函数关闭模态框。
2. 代码+详细注释说明
// @/components/Modal/index.tsx
import React, { useEffect } from "react";
import classNames from "classnames";
import OutsideClickHandler from "react-outside-click-handler";
import styles from "./index.module.scss";
type Props = {
// 是否显示模态框
show: boolean;
// 模态框内容
children: React.ReactNode;
// 关闭模态框时的回调函数
onClose: () => void;
// 自定义样式类名
className?: string;
};
export default (props: Props) => {
const { show, children, onClose, className } = props;
// 监听 Esc 键关闭模态框
useEffect(() => {
const handlerKeyDown = (event: KeyboardEvent) => {
if (event.keyCode === 27) {
onClose();
}
window.addEventListener("keydown", handlerKeyDown);
return () => {
window.removeEventListener("keydown", handlerKeyDown);
};
};
}, [onClose]);
// 当模态框不可见时,返回 null,不渲染模态框组件
if (!show) {
return null;
}
return (
<>
{/* 模态框遮罩层 */}
<div className={styles.modalMask}>
{/* 外部点击区域 */}
<OutsideClickHandler onOutsideClick={onClose}>
{/* 模态框主体 */}
<div className={classNames(styles.modalWrap, className)}>{children}</div>
</OutsideClickHandler>
</div>
</>
);
};
------------------------------------------------------------------------------
// @/components/Modal/index.module.scss
.modalMask {
position: fixed;
top: 0;
bottom: 0;
inset-inline-end: 0;
inset-inline-start: 0;
z-index: 1000;
height: 100%;
background-color: rgba(0, 0, 0, 0.45);
.modalWrap {
position: absolute;
z-index: 10;
top: 200px;
left: 50%;
transform: translateX(-50%);
background-color: #ffffff;
border-radius: 4px;
max-width: 90%;
box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
@media screen and (max-width: 750px) {
max-width: calc(100vw - 32px);
}
}
}
3. 使用方式
// 引入组件
import Modal from "@/pages/components/commonDialog";
// 使用
<Modal show={show} onClose={onClose}>
<div style={{ padding: "20px" }}>这是一个模态框</div>
</Modal>
4. 效果展示
总结
下一篇讲【全局常用组件弹窗Dialog封装】。关注本栏目,将实时更新。