详解使用React制作一个模态框

模态框是一个常见的组件,下面让我们使用 React 实现一个现代化的模态框吧。

组件设计

模态框想必大家都很熟悉,是工作中常用的组件,可以让我们填写或展示一些信息而不必打开一个新页面。在开始编码之前,我们先来了解一个 React 模态框组件应该如何设计。

React 是一个状态(数据)驱动的前端框架,一个模态框最重要的状态就是打开和关闭,visible,当 visible 为 true 时,模态框打开,反之亦然。

由于 React 所提倡的是一种声明式,组件化的开发体验,每个组件都是 状态 => 界面 的映射,所以,我们把 visible 做为模态框组件的一个 prop,通过传入 prop 来控制

模态框的显示和隐藏,同时该组件还接受一个 onClose 的 prop,用来关闭模态框。

<Modal visible={modalVisble} onClose={this.onModalClose} />

一个完整的模态框还需要标题和内容,因此,我们还需要一个 header 的 prop 来传递模态框的 header,并把 Modal 组件的 children 作为模态框的内容 content。最后,我们的模态框 Modal 的调用方式是这样的:

import React, { useEffect, useState } from 'react'; import Modal from './components/modal'; function App() { const [modalVisible, setModalVisible] = useState(true); const openModal = function() { setModalVisible(true) }; const closeModal = function() { setModalVisible(false) }; return ( <> <button onClick={openModal}>Click</div> <Modal visible={modalVisible} onClose={closeModal} header="Create a modal"> <p>This is my content</p> </Modal> </> ); } export default App;

这里使用了 hooks,请升级到最新版本的 react 来体验。

实际上,一个完整的模态框组件还应该提供一些额外的配置来方便用户使用,比如 header 和 content 的自定义样式 headerClassName,contentClassName,定制操作按钮的 footer,控制是否显示关闭按钮的 showClose 等等,
但这里为了保持教程的简单,这些简单的配置就不一一实现了,如果感兴趣可以自行练习。

确定了我们的模态框的调用方式,现在我们来总结一下完整的模态框应该具备那些特性:

模态框组件应该挂载在 body 的第一层中,不要将模态框放置到父组件中,因为模态框放置到父组件中很容易受到其他元素的干扰。

模态框显示后,模态框背后的背景不能随着鼠标滚轮而滚动。

点击模态框的遮罩层后,应该关闭模态框。

基础功能

上面分析玩模态框的功能后,让我们先开始实现一版最基础的模态框。从 HTML 结构上来讲,模态框组件分为 overlay 遮罩层和 content 内容两部分组成,其中 content 里面还应该分为 header, content, footer(这里我们没有实现)三部分组成。
所以,模态框的最基本的结构如下

import React, { PureComponent } from 'react'; class Modal extends PureComponent { render() { const { visible, onClose, header, children } = this.props; return ( <div className={`overlay ${visible ? 'visible' : ''}`}> <div className="content"> <div className="header"> {header} <button onClick={onClose}>Close</button> </div> <div className="content">{children}</div> </div> </div> ); } }

由于 overlay 元素是模态框组件的最外层的容器,所以我们可以通过控制 overlay 的显示和隐藏(在上面的基础结构中,通过 visible 属性的值来给 overlay 添加或删除类 'visible' 来控制 )实现模态框的打开关闭效果。在这里我们使用 display 实现控制 overlay 的显示和隐藏(这样在关闭时并没有删除该模态框,方便下次打开可以保存内容),同时 overlay 还是一个占据整个窗口的半透明暗色背景,所以 overlay 的样式应该为

.overlay { display: none; position: fixed; top: 0; right: 0; bottom: 0; right: 0; background: rgba(0, 0, 0, 0.3); visibility: hidden; } .overlay.visible { display: block; visibility: visible; }

然后就是 content 中元素的样式,都很简单,大家看一下就好了,可以根据自己的组件规范修改这些样式。

.container { margin: 80px auto; width: 80%; min-height: 800px; background: #fff; border-radius: 4px; } .header { display: flex; justify-content: space-between; padding: 16px; font-size: 24px; border-bottom: 1px solid #d3d3d3; } .body { padding: 16px; } .closeBtn { outline: none; border: none; appearance: none; font-size: 18px; color: #d5d5d5; cursor: pointer; }

这样,我们最基础的一版模态框就做好了,但是这个模态框是渲染在父组件中,那么如何才能将这个模态框放到 body 下,作为顶层元素呢?我们可以使用 Portal 这个 React 新提供的功能。

使用 portal 将模态框送到 body 中

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6917976bae726c476a1787caf39a62fd.html