React+TS前台项目实战(八)-- 全局常用组件模态框Modal封装

文章目录

  • 前言
  • Modal模态框组件
    • [1. 功能分析](#1. 功能分析)
    • [2. 代码+详细注释说明](#2. 代码+详细注释说明)
    • [3. 使用方式](#3. 使用方式)
    • [4. 效果展示](#4. 效果展示)
  • 总结

前言

今天这篇主要讲项目中经常会用到的模态框Modal组件封装。模态框可用在很多地方,比如弹窗Dialog使用、消息提示Message使用等都可以在外层套上Modal组件,下一讲会讲到Dialog组件的封装,就是基于模态框进行开发的。


Modal模态框组件

1. 功能分析

(1)用于在页面上显示一个弹出窗口,由遮罩层和主体部分组成。遮罩层覆盖整个屏幕,用于阻止点击穿透到下层内容。主体部分包含传入的 children,即模态框的内容。

(2)组件使用 useEffect 钩子来监听 Esc 键的按下,并在按下时关闭模态框

(3)OutsideClickHandler 组件用于检测模态框外部的点击,并调用 onClose 回调函数关闭模态框。

2. 代码+详细注释说明

c 复制代码
// @/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. 使用方式

c 复制代码
// 引入组件
import Modal from "@/pages/components/commonDialog";
// 使用
<Modal show={show} onClose={onClose}>
  <div style={{ padding: "20px" }}>这是一个模态框</div>
</Modal>

4. 效果展示


总结

下一篇讲【全局常用组件弹窗Dialog封装】。关注本栏目,将实时更新。

相关推荐
阿珊和她的猫1 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
加班是不可能的,除非双倍日工资5 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi6 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip6 小时前
vite和webpack打包结构控制
前端·javascript
excel7 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国7 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼7 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy7 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT7 小时前
promise & async await总结
前端
Jerry说前后端7 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化