网站首页 > 技术文章 正文
当下前端届最火的技术之一莫过于React + Redux + webpack的技术结合。最近公司内部也正在转react,这周主要做了个React的modal组件,接下来谈下具体实现过程。
基本的HTML结构
虽然React基于虚拟DOM,但他的JSX语法还是离不开最基本的HTML。第一步要做的就是通过HTML&&CSS实现Dialog垂直水平居中框。HTML结构如下:
<div className="m-mask"></div>
<div className="m-dialog">
<div className="md-dialog">
<div className="md-dialog-title">
<h4>{title}</h4>
<span className="btn">
<i className="iconfont">×</i>
</span>
</div>
<div className="md-dialog-content">
{this.props.children}
</div>
<div className="md-dialog-foot">
<a href="#" className="btns">取消</a>
<a href="#" className="btns btns-blue">确定</a>
</div>
</div>
</div>
ps: JSX语法的className对应于HTML中的class,其次文中的iconfont图标被换成了×
。
然后写下对应的CSS样式。此处主要说明一下主要的样式布局原理,细节略过。
Modal框的背景mask样式通过position:absolute + top/right/bottom/left:0 + height: 100%
实现。
不定宽高的主体内容水平垂直居中的实现通过position:relative + top/left: 50% + translate(-50%, -50%)
实现。
React Modal Component
有了已经想好的布局样式,开始实现最基本的Modal组件。因为需要动态控制组件的显隐,所以组件的显隐在内部要通过state方便控制,而其他属性则通过props实现。modal.js代码如下:
import React, { Component, PropTypes } from 'react'
const defaultProps = {
show: false,
title: '',
zIndex: 1000,
onOk: => {},
onCancel: => {},
}
const propTypes = {
title: PropTypes.string,
zIndex: PropTypes.number,
onOk: PropTypes.func,
onCancel: PropTypes.func,
}
export default class Modal extends Component {
constructor(props) {
super(props)
this.state = {show: props.show}
}
render {
return (
// JSX语法的HTML
);
}
}
Modal.defaultProps = defaultProps
Modal.propTypes = propTypes
不过显隐内部通过state控制,但父组件还是需要通过props传递初始默认值。而且来回调用同一个modal时,父组件是通过props中的show属性控制。内部的state还是第一次调用时传入的props值。这样无法导致及时控制显隐。此时react的componentWillReceiveProps出场,完美解决这个bug。
俗话说bug是解不完的,虽然上面的组件勉强可以正常使用,但是用于样式通过绝对定位来做的,无形中导致了另外一个坑,如果Modal的父组件采用了相对或者绝对定位,即影响了Modal组件的定位,就会存在Modal出现在了某个div中,而不是理想的body中。bug复现如下:
unstable_renderSubtreeIntoContainer登场
为了保证我们的组件始终处于body中,采取了ReactDOM中的的这个不太正式的API。语法很简单:
ReactDOM.unstable_renderSubtreeIntoContainer(parent, component, dom)
parent一般是this,component是Modal,dom是div 代码实现如下:
export default class extends Component {
appendMaskIntoDoc {
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
<Modal {...this.props}>
{this.props.children}
</Modal>,
this.container
)
}
componentDidMount {
this.container = document.createElement('div')
document.body.appendChild(this.container)
this.appendMaskIntoDoc
}
componentDidUpdate {
this.appendMaskIntoDoc
}
componentWillUnmount {
document.body.removeChild(this.container)
}
render {
return null
}
}
API形式
此时,Modal组件已经成功做出来了。父组件可以成功调用,效果如下:
不过,偷偷see了下蚂蚁金服官网的Modal组件调用,还有一种API形式的调用。于是也简单实现了下。这里,简单说下实现思路吧。
Confirm function内部通过setState方法函数接受的参数传递给Modal的父组件dialog,onOk的promise异步回调则是在dialog内部通过处理之后再传递给Modal组件。
此处我是通过正则表达式检测new Promise
,如果属于Promise,则给onOk绑定then,内部调用setState控制Modal的隐藏。不过在调用Confirm function之前,
dialog组件已经被render进ReactDOM中,render之前则需要dom节点,就需要能获取到document节点。然后手动创建空div节点添加到body中。
此处代码有点长,省略咯。
- 上一篇: JS如何判断文字被ellipsis了?
- 下一篇: Js基础3:节点创建
猜你喜欢
- 2025-05-15 网页中如何实现点击按钮将文本复制到剪贴板?
- 2025-05-15 JavaScript 事件——“事件类型”中“UI事件”的注意要点
- 2025-05-15 WEB大前端进阶之模块化
- 2025-05-15 Ajax跨域请求的两种实现方式
- 2025-05-15 多可文档系统在Edge, Chrome等浏览器启动客户端的代码及方法
- 2025-05-15 vue下载excel文件方法
- 2025-05-15 three.js 入门
- 2025-05-15 判断变量是否为数组
- 2025-05-15 Js基础3:节点创建
- 2025-05-15 JS如何判断文字被ellipsis了?
- 05-15总结雅虎前端性能优化技巧(16条)
- 05-15日常生活中吃雪莲果有养生功效也有危害
- 05-15API 安全之认证鉴权
- 05-15Chaosblade: 阿里一个超级牛逼的混沌实验实施工具
- 05-15膨来仙岛丨搞电竞的都是什么成分?
- 05-15大事全知晓!2022年新闻日历来了!
- 05-15你是有多久没看过麦田圈了?一篇文章全面回顾2015麦田圈季
- 05-15魔兽世界9.1 刻希亚寻找宝箱、稀有WA(转自nga)
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)