动手实现react Modal组件
Modal组件
长话不多说,接下来让我们来动手实现一个react Modal组件。
我们先来看一下实际效果
Modal的布局
首先,让我们先思考下一个Modal组件的布局是怎么样的。
我们先拿一个基本的Modal样例来分析下。
如上图所示,一个Modal组件可以分为mask、header、body和footer四部分,mask就不用说了,header主要是显示title和关闭按钮,body则是使用者自己传的内容,footer主要是按钮控件。
Modal组件的参数(props)
我们确定了Modal组件的布局之后,我们来思考一下Modal组件可支持传递的参数。
作为一个Modal组件,总要有标题(title)吧?要有用户自定义传入的内容(children),还有一个确定按钮文案(okText)和一个取消按钮文案(cancelText)吧,并且允许用户传入点击确定按钮的回调函数(onOk)和点击取消按钮的回调函数(onCancel)。也需要有一个控制Modal是否显示的标志吧(visible)。所以,大体上有以下7个变量。
Modal的样式
首先,根据Modal组件的布局和参数,我们可以确定react Modal的render函数如下:
我们都知道,Modal会覆盖在其他元素上面,并且主要分为两部分,一部分为mask阴影部分,一部分为主体内容,而且主体部分会覆盖在阴影部分上面。让我们一步步来实现这个效果。
实现mask效果
.modal-mask {
// 让mask铺满整屏
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: black;
opacity: 0.6;
// 让mask覆盖在其他元素上面
z-index: 1000;
}
实现主体内容的样式,让其覆盖在其他元素(包括mask)上面,每一部分的作用可以看注释
.modal-container {
// 让Modal的主体内容全局居中,通过position: fix以及top和left的50%让主体内容的左上角居中,再通过transform:translate(-50%, -50%)来让主体内容正确居中。
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); background: white;
min-width: 500px;
border-radius: 4px;
// 设置主体内容的z-index高于mask的,从而可以覆盖mask
z-index: 1001;
}
接下来是body、footer和header样式的实现,这个就直接贴代码了。
.modal-title {
padding: 30px;
color: black;
font-size: 20px;
border-bottom: 1px solid #e8e8e8;
} .modal-body {
padding: 30px;
font-size: 14px;
border-bottom: 1px solid #e8e8e8;
} .modal-footer {
text-align: center;
padding: 30px;
display: flex;
} .modal-footer .btn {
flex: 1;
height: 32px;
text-align: center;
} .modal-footer .modal-cancel-btn {
background: white;
margin-right: 30px;
border-color: #d9d9d9;
border-radius: 4px;
} .modal-footer .modal-confirm-btn {
background: #1890ff;
color: white;
}
Modal的交互逻辑实现
实际上Modal的交互是很简单的,一般的调用方式如下:
由外部传递自定义的body内容以及一些自定义的属性(比如title,点击按钮的回调还有Modal的标题)
我们先定义Modal组件里的props
设置一些默认的props,当用户未传入参数的时候,则使用默认的props
实现render函数,根据用户传入的参数以及默认参数来渲染Modal节点,如果用户传入的visible属性为false(Modal不可见),则返回null,否则,返回Modal节点。
这样,一个简单的react Modal组件就完成了,上面的代码可以在https://github.com/chenjigeng/empty 查看,并且可以直接看到一个demo例子。
效果图如下:
最后再贴一下完整的Modal组件代码
// Modal.tsx
import * as React from 'react';
import './Modal.css';
interface IModalProps {
children: React.ReactChild | React.ReactChildren | React.ReactElement<any>[],
title?: React.ReactChild,
visible: boolean,
onOk?: () => void,
onCancel?: () => void,
okText?: string,
cancelText?: string,
}
export default class Modal extends React.Component<IModalProps> {
public static defaultProps = {
cancelText: '取消',
okText: '确定',
visible: false,
}
public render() {
const { title, visible, okText, cancelText, children, onOk, onCancel } = this.props;
if (!visible) {
return null;
};
return (
<div>
<div className="modal-mask" onClick={onCancel}/>
<div className="modal-container">
<div className="modal-header">
<div className="modal-title">{title}</div>
</div>
<div className="modal-body">
{children}
</div>
<div className="modal-footer">
<button className="modal-cancel-btn btn" onClick={onCancel}>{cancelText}</button>
<button className="modal-confirm-btn btn" onClick={onOk}>{okText}</button>
</div>
</div>
</div>
)
}
}
// Moda.css
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: black;
opacity: 0.6;
z-index: 1000;
}
.modal-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
min-width: 500px;
border-radius: 4px;
z-index: 1001;
}
.modal-title {
padding: 30px;
color: black;
font-size: 20px;
border-bottom: 1px solid #e8e8e8;
}
.modal-body {
padding: 30px;
font-size: 14px;
border-bottom: 1px solid #e8e8e8;
}
.modal-footer {
text-align: center;
padding: 30px;
display: flex;
}
.modal-footer .btn {
flex: 1;
height: 32px;
text-align: center;
}
.modal-footer .modal-cancel-btn {
background: white;
margin-right: 30px;
border-color: #d9d9d9;
border-radius: 4px;
}
.modal-footer .modal-confirm-btn {
background: #1890ff;
color: white;
}
本文地址在->本人博客地址, 欢迎给个 start 或 follow
动手实现react Modal组件的更多相关文章
- 实现一个带有动效的 React 弹窗组件
我们在写一些 UI 组件时,若不考虑动效,就很容易实现,主要就是有无的切换(类似于 Vue 中的 v-if 属性)或者可见性的切换(类似于 Vue 中的 v-show 属性). 1. 没有动效的弹窗 ...
- React对话框组件实现
当下前端届最火的技术之一莫过于React + Redux + webpack的技术结合.最近公司内部也正在转react,这周主要做了个React的modal组件,接下来谈下具体实现过程. 基本的HTM ...
- beeshell —— 开源的 React Native 组件库
介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...
- React实现组件全屏化
介绍 本文基于React+antd,给大家演示一个完整的全屏demo. 起因是开发今天给我提了一个sql编辑器输入框比较小,不支持放大,不太方便.希望能够全屏显示,联想到自己以后可能也会需要,便研究并 ...
- React 函数组件
React 函数组件 1.定义方式 React 函数组件是指使用函数方法定义的组件. 定义方式:与函数的定义方式相同,需要将内容 return 出来,需要注意的是最外层只有一个标签或者使用<&g ...
- 移动web端的react.js组件化方案
背景: 随着互联网世界的兴起,web前端开发的方式越来越多,出现了很多种场景开发的前端架构体系,也对前端的要求日益增高,早已经不是靠一个JQuery.js来做前端页面的时代了,而今移动端变化最大,近 ...
- 利用bootstrap的modal组件自定义alert,confirm和modal对话框
由于浏览器提供的alert和confirm框体验不好,而且浏览器没有提供一个标准的以对话框的形式显示自定义HTML的弹框函数,所以很多项目都会自定义对话框组件.本篇文章介绍自己在项目中基于bootst ...
- Griddle, griddle-react 一个REACT 表格组件
Griddle, griddle-react 一个REACT 表格组件: http://griddlegriddle.github.io/Griddle/index.html
- React Native组件之Text
React Native组件之Text相当于iOS中的UILabel. 其基本属性如下: /** * Sample React Native App * https://github.com/face ...
随机推荐
- Aizu 0525 Osenbei 搜索 A
Aizu 0525 Osenbei https://vjudge.net/problem/Aizu-0525 题目: IOI製菓では,創業以来の伝統の製法で煎餅(せんべい)を焼いている.この伝統の製法 ...
- vim折叠设置(转载)
vim折叠设置(转载) set foldmethod=indent "set default foldmethod"zi 打开关闭折叠"zv 查看此行zm 关闭折叠zM ...
- Python开发——5.函数
一.函数的定义 def test(x) "The Function definitions" x += return x def:定义函数的关键字 test:函数名 ():定义形参 ...
- SPI通信协议(非原创,转载他人,用于学习)
SPI通信协议:1.SPI主从模式:2.数据信号的相位与极性:3.数据帧的格式. 一.什么是SPI? SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 Moto ...
- yii2.0 点击验证码图片不刷新
修改vender\yiisoft\yii2\captcha\CaptchaAction下的run方法 public function run(){ if (Yii::$app->request- ...
- 《Pro git》
可以通过阅读 CODING 工程师参与翻译的 <Pro Git> 进一步掌握 Git 版本控制系统. https://git-scm.com/book/zh/v2
- react-router V4中的url参数
概述 之前写过react在router中传递数据的2种方法,但是有些细节没有理清楚,现在补上,记录下来,供以后开发时参考,相信对其他人也有用. 参考资料:stackoverflow react rou ...
- Zabbix-2--安装--LAMP/LNMP详细总结
- Iptables-redhat/centos
6用iptables 7默认用firewalld firewalld 与 iptables 过滤点,表 做nat是使用postrouting,prerouting表 Samba服务所使用的端口和协议: ...
- Typescript 学习笔记二:数据类型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...