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 小时前
Lodash源码阅读-dropRight
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-drop
前端·javascript·源码阅读
程序猿chen2 小时前
安全岗の夺命连环问:(第壹篇)从XSS到0day的灵魂拷问
前端·git·安全·面试·跳槽·xss·改行学it
前端_yu小白3 小时前
js异步机制
前端·javascript·async·promise·await·js异步·回调地狱
Spider Cat 蜘蛛猫3 小时前
chrome extension开发框架WXT之WXT Storage api解析【补充说明一】
前端·javascript·chrome
程序猿John6 小时前
ES6 新增特性 箭头函数
前端·javascript·es6
百锦再7 小时前
五种常用的web加密算法
前端·算法·前端框架·web·加密·机密
@大迁世界7 小时前
彻底改变我 React 开发方式的组件模式
前端·javascript·react.js·前端框架·ecmascript
William Dawson8 小时前
【Vue 3 + Element Plus 实现产品标签的动态添加、删除与回显】
前端·javascript·vue.js
拉不动的猪8 小时前
项目基础搭建时的一些基本注意点
前端·javascript·面试