动手实现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 ...
随机推荐
- BZOJ4381 : [POI2015]Odwiedziny / Luogu3591[POI2015]ODW - 分块+树剖
Solution 在步伐$pace$比较小的时候, 我们发现用前缀和直接维护会很快 而在$pace$比较大的时候, 则暴力往上跳会最优 设$blo= \sqrt{N}$ 若$pace<=blo$ ...
- 设计模式学习心得<抽象工厂模式 Abstract Factory>
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
- service 设计问题
今天写了一段让自己尴尬的代码,就是在一个方法中调用了两个 service 方法,而我为每个service 都定义了 事物回滚. 然后郁闷了,我执行请求调用该方法, 发现第二个service方法执行失败 ...
- A - ACboy needs your help again!
ACboy was kidnapped!! he miss his mother very much and is very scare now.You can't image how dark th ...
- 使用jquery load遇到一个问题解决
1.环境 动态加载页面后给页面中的控件动态赋值,赋完更新后一闪值就没了. 2.原因 load()方法是异步加载,页面没有加载完就开始赋值,导致情况出现. 3.解决 加载完成后赋值 $(&qu ...
- ssm框架中处理json格式的数据步骤
1.导架包 <!--处理json--> <dependency> <groupId>com.fasterxml.jackson.core</groupId&g ...
- [solution] JZOJ-5781 秘密通道
JZOJ-5781[秘密通道 ]solution 题面 Description 有一副$nm$的地图,有$nm$块地,每块是下列四种中的一种: 墙:用#表示,墙有4个面,分别是前面,后面,左面,右面. ...
- Codeforces Round #539--1113B - Sasha and Magnetic Machines
https://codeforces.com/contest/1113/problem/B 思想不难,但是在比较大小的时候,我选择了很笨的方法,我用两个数变化之后的差值大小来进行选择,然后最后再进行数 ...
- day15_雷神_前端03
# 前端 day03 内容回顾 javascript: 1.ECMAScript5.0 es6(阮一峰) es7 es8 (1)声明变量 var let (2)内置函数 Date Math.rando ...
- Java高级开发必会的50个性能优化细节
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...