当前位置: 首页 > news >正文

React 模态框的设计(二)

自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求,比如关于弹窗,每个应用都会用到,但是有时我们使用的框架中提供的弹窗功能也是功能有限,无法满足我们的应用需求,今天 我来讲一下在React中如何自定义各种样式的弹窗。相信通过这篇文章,你能在自定义组件方面技能有一个质的提升。相关的知识能够掌握的更加牢固。

先看最终的效果:
在这里插入图片描述

首先本实例都是在MUI及基础上设计的,样式部分我使用了emotion-react

弹窗的设计有两种方案,一种是直接把弹窗组件嵌入到页面中,用的时候让它直接显示或关闭即可,一般的UI框架都是采用这种方法。这种使用方法有一个好处是不受浏览器插件的影响,尤其是广告拦截插件的影响。但使用上有点不方便,必须要在使用弹窗的组件中加入这个弹窗,使用上不太方便。另一种方案是动态创建弹窗组件,在使用的时候直接alert就可以了。就像使用js原生的弹窗一样简单。本篇文章就是围绕这种设计思路设计一个优雅的弹窗组件。

弹窗遮罩

遮罩很简单,就一个div, 在MUI里就是一个Box组件。

const maskCss = css`position: fixed;background-color: rgba(0,0,0,0.6);border-radius: 5px;top: 0px;left: 0px;width: 100%;height: 100%;overflow: hidden;z-index: 999;display: flex;justify-content: center;align-items: center;`;

这是遮罩的样式,我直接赋于一个Box就好了。

/** @jsxImportSource @emotion/react */
import { css, jsx, keyframes } from '@emotion/react'
import { useState, useRef, useEffect, useCallback } from 'react';
import Box from '@mui/material/Box';export default function Model(props) {return (<Box css={maskCss}></Box>)
}

我们再来临时创建一个简单的弹窗主体

/** @jsxImportSource @emotion/react */
import { css, jsx, keyframes } from '@emotion/react'
import React, { useState } from 'react';
import Box from '@mui/material/Box';const maskCss = css`position: fixed;background-color: rgba(0,0,0,0.6);border-radius: 5px;top: 0px;left: 0px;width: 100%;height: 100%;overflow: hidden;z-index: 999;display: flex;justify-content: center;align-items: center;`;const modelCss = css`position: relative;background-color: white;border: 1px solid #ccc;border-radius: 5px;overflow: hidden;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);width: 400px;height: 300px;`const titleCss = css`background-color: #f0f0f0;padding: 8px;cursor: move;`;const modelContentCss = css`padding: 16px;`;const Modal = (props) => {const {onClose} = props;const onClick = (e) => { console.log('target:', e.target.className);}return (<Box css={maskCss}onClick = {onClose}><Box css={modelCss}><Boxcss={titleCss}className=".modelHandler">这是标题</Box><Box css={modelContentCss}>这是弹窗内容</Box></Box></Box>);
};export default Modal;

这是一个简单的弹窗,如何让它弹出来呢。我的想法是动态的把这个弹窗插入到documentbody

// 创建一个div容器,作为弹窗的根节点
const modelContainer = document.createElement("div");// 将div容器添加到body中
document.body.appendChild(modelContainer);

上面我只是创建了一个dom节点,但我们必须把这个dom节点添加到React中才能真实的渲染出来。

// 创建一个根节点
const modelRoot = ReactDOM.createRoot(modelContainer);

然后渲染出来

modelRoot.render(<Model />
);

这样就在body中插入了model组件了,并且能渲染出来。当然能挂载我们还要有卸载才行。很简单

// 卸载事件
const unmountEvent = () => {modelContainer.remove();
}

我们将上面的弹窗方法整合成一个hook就好了,这样调用起来就相当的哇塞了。

import ReactDOM from 'react-dom/client';
import Model from './_Model';//可高度自定义的统一弹窗。
export default function useAlert() {return (configure) => {// 创建一个div容器,作为弹窗的根节点const modelContainer = document.createElement("div");// 将div容器添加到body中document.body.appendChild(modelContainer);// 创建一个根节点const modelRoot = ReactDOM.createRoot(modelContainer);// 卸载事件const unmountEvent = () => {modelContainer.remove();}modelRoot.render(<ModelonClose={unmountEvent}{...configure}>{configure.component || null}</Model>);}}

我们把卸载事件传递给了Model,在遮罩点击事件上调用,这样就能开发弹窗也能关闭弹窗。

我们这样调用就好了:

const alert = useAlert();
alert();

你看一个基本的弹窗就设计完了。

相关文章:

React 模态框的设计(二)

自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求&#xff0c;比如关于弹窗&#xff0c;每个应用都会用到&#xff0c;但是有时我们使用的框架中提供的弹窗功能也是功能有限&#xff0c;无法满足我们的应用需求&#xff0c;今天…...

操作符详解3

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 前面我们已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作 符&#xff0c;今天继续介绍一部分。 目录 1.操作符的分类 2…...

【C语言基础】:操作符详解(一)

文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…...

通俗易懂分析:Vite和Webpack的区别

1、对项目构建的理解 先从浏览器出发&#xff0c; 浏览器是由浏览器内核和JS引擎组成&#xff1b;浏览器内核编译解析html代码和css代码&#xff0c;js引擎编译解析JavaScript代码&#xff1b;所以从本质上&#xff0c;浏览器只能识别运行JavaScript、CSS、HTML代码。 而我们在…...

OpenCart程序结构与业务逻辑

一、程序业务逻辑说明 在 OpenCart 中&#xff0c;index.php 文件是整个应用程序的入口文件&#xff0c;它负责初始化应用程序并调度请求。以下是 index.php 文件加载执行的流程&#xff1a; 1. **设置路径常量&#xff1a;** - index.php 首先定义了一些重要的路径常量&…...

软件License授权原理

软件License授权原理 你知道License是如何防止别人破解的吗?本文将介绍License的生成原理,理解了License的授权原理你不但可以防止别人破解你的License,你甚至可以研究别人的License找到它们的漏洞。喜欢本文的朋友建议收藏+关注,方便以后复习查阅。 什么是License? 在…...

C/C++实现老鼠走迷宫

老鼠形象可以辨认&#xff0c;可以用上下左右操纵老鼠;正确检测结果&#xff0c;若老鼠在规定的时间内走到粮仓&#xff0c;提示成功&#xff0c;否则提示失败。代码分为3个文件&#xff1a;main.cpp、play.h、play.cpp。 main.cpp: #include <iostream> #include <…...

[Linux]文件基础-如何管理文件

回顾C语言之 - 文件如何被写入 fopen fwrite fread fclose fseek … 这一系列函数都是C语言中对文件进行的操作&#xff1a; int main() {FILE* fpfopen("text","w");char str[20]"write into text";fputs(str,fp);fclose(fp);return 0; }而上…...

bat 查找文件所在

脚本 在批处理文件&#xff08;.bat&#xff09;中查找文件所在的目录&#xff0c;你可以使用dir命令结合循环和条件语句来实现。以下是一个简单的示例&#xff0c;演示如何在批处理文件中查找指定文件并输出其所在目录&#xff1a; echo off setlocal enabledelayedexpansio…...

程序员的守护神:为何电脑永不熄灭?

在这个信息时代&#xff0c;程序员成了推动社会进步的“隐形英雄”。他们通宵达旦&#xff0c;手指在键盘上跳跃&#xff0c;创造出一个个令人惊叹的数字世界。有趣的是&#xff0c;你可能注意到了一个现象&#xff1a;程序员似乎总是不关电脑。这并非他们对电脑上瘾&#xff0…...

Kafka快速实战以及基本原理详解

Kafka快速实战以及基本原理详解 基本概念 Kafka是一个分布式、支持分区、多副本&#xff0c;基于ZK的分布式消息系统&#xff0c;最大的特性就是可以实时的处理大量数据以满足各种需求场景&#xff0c;比如Hadoop的批处理系统、低延迟的实时系统、Storm/Spark流式处理引擎、日…...

微信小程序(4)- 事件系统和模板语法

1. 事件系统 1.1 事件绑定和事件对象 小程序中绑定事件与在网页开发中绑定事件几乎一致&#xff0c;只不过在小程序不能通过 on 的方式绑定事件&#xff0c;也没有 click 等事件&#xff0c;小程序中绑定事件使用 bind 方法&#xff0c;click 事件也需要使用 tap 事件来进行代…...

【Java多线程】对线程池的理解并模拟实现线程池

目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多&#xff0c;例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是&#xff1a;&#xff08;提高效率&#xff09; 1…...

python连接mysql数据库

连接MySQL数据库&#xff0c;通常我们会使用Python的mysql-connector-python库。下面是一个基本的示例来展示如何使用Python连接到MySQL数据库。 首先&#xff0c;确保你已经安装了mysql-connector-python库。如果没有&#xff0c;你可以使用pip来安装它&#xff1a; pip ins…...

docker用法

首先需要去docker官网注册你的账号&#xff0c;记住账号名称和密码&#xff1b; 然后在本地执行&#xff1a; docker login登录OK。 把ubuntu下载到本地&#xff1a; sudo docker pull ubuntusudo docker images输出&#xff1a; REPOSITORY TAG …...

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…...

C#与VisionPro联合开发——跳转页面

1、跳转页面并打开相机 From1 所有代码展示 using System; using System.IO; using System.Windows.Forms; //引入VisionPro命名空间 using Cognex.VisionPro;namespace ConnectCamera {public partial class Form1 : Form {public Form1() {InitializeComponent();}CogAcqFif…...

服务端测试开发必备技能:Mock测试

什么是mock测试 Mock 测试就是在测试活动中&#xff0c;对于某些不容易构造或者不容易获取的数据/场景&#xff0c;用一个Mock对象来创建以便测试的测试方法。 Mock测试常见场景 无法控制第三方系统接口的返回&#xff0c;返回的数据不满足要求依赖的接口还未开发完成&#…...

vue3中ref创建变量取值时自动补充 .value 插件 volar

插件 TypeScript Vue Plugin (Volar) 设置中配置...

clickhouse的docker部署与springboot整合

注意:镜像bitnami/clickhouse包含服务端和客户端,yandex版本需要使用yandex/clickhouse-server,yandex/clickhouse-server docker启动命令(允许空密码 -e ALLOW_EMPTY_PASSWORD=yes),clickhouse版本不同,配置文件在的位置也会不一样/etc/clickhouse-server/config.xml d…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...