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封装】。关注本栏目,将实时更新。

相关推荐
xw511 分钟前
uni-app中v-if使用”异常”
前端·uni-app
!win !30 分钟前
uni-app中v-if使用”异常”
前端·uni-app
IT_陈寒1 小时前
Java 性能优化:5个被低估的JVM参数让你的应用吞吐量提升50%
前端·人工智能·后端
南囝coding1 小时前
《独立开发者精选工具》第 018 期
前端·后端
小桥风满袖2 小时前
极简三分钟ES6 - ES9中for await of
前端·javascript
半花2 小时前
i18n国际语言化配置
前端
编程贝多芬2 小时前
Promise 的场景和最佳实践
前端·javascript
Asort2 小时前
JavaScript 从零开始(四):基础语法详解——从变量声明到数据类型的完全指南
前端·javascript
木木jio2 小时前
前端大文件分片上传 —— 基于 React 的工程化实现
前端·javascript
南雨北斗2 小时前
JS的对象属性存储器
前端