環(huán)境搭建
用 create-react-app 快速搭建一個(gè) react 的開發(fā)環(huán)境,沒有用過的童鞋可參考官網(wǎng)
目錄
- 新建文件
src/modal/index.jsx, 并寫入一段簡單的測試代碼
import React, { Component } from 'react';
import './index.css';
class Modal extends Component {
render() {
return <div className="modal">
這是一個(gè)modal組件
</div>
}
}
export default Modal;
新建文件
src/modal/index.css修改
src/App.js, 引入 Modal 組件
import React, { Component } from 'react';
import Modal from './modal';
import './App.css';
class App extends Component {
render() {
return (
<Modal / >
);
}
}
export default App;
- 在命令行輸入
npm start,出現(xiàn)如下結(jié)果,則表示環(huán)境搭建成功

modal_init.png
什么是 modal
- 標(biāo)題區(qū)
- 內(nèi)容區(qū)
- 控制區(qū)
- mask
modal 骨架實(shí)現(xiàn)
修改
src/modal/index.jsx
import React from 'react';
export default class Modal extends React.Component {
render() {
return (
<div>
<div>
<div>標(biāo)題區(qū)</div>
<div>內(nèi)容區(qū)</div>
<div>
<button>取消</button>
<button>確定</button>
</div>
</div>
<div>mask</div>
</div>
)
}
}
modal 樣式實(shí)現(xiàn)
修改
src/modal/index.jsx
import React from 'react';
export default class Modal extends React.Component {
render() {
return (
<div className='wrapper'>
<div className='modal'>
<div className='title'>標(biāo)題區(qū)</div>
<div className='content'>內(nèi)容區(qū)</div>
<div className='operator'>
<button className='close'>取消</button>
<button className='confirm'>確定</button>
</div>
</div>
<div className='mask'>mask</div>
</div>
)
}
}
修改
src/modal/index.css
.modal {
width: 300px;
height: 200px;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
z-index: 2000;
background: #fff;
border-radius: 2px;
box-shadow: inset 0 0 1px 0 #000;
}
.title {
width: 100%;
height: 50px;
line-height: 50px;
padding: 0 10px;
}
.content {
width: 100%;
height: 100px;
padding: 0 10px;
}
.operator {
width: 100%;
height: 50px;
}
.close, .confirm {
width: 50%;
border: none;
outline: none;
color: #fff;
background: #4CA791;
cursor: pointer;
}
.close:active, .confirm:active {
opacity: 0.6;
transition: opacity 0.3s;
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #000;
opacity: 0.6;
z-index: 1000;
}
效果如圖所示:

modal_css.png
modal 功能開發(fā)
先思考一下 modal 組件需要實(shí)現(xiàn)哪些基本功能:
- 可以通過 visible 控制 modal 的顯隱
- 標(biāo)題區(qū) 和 內(nèi)容區(qū) 可以自定義顯示內(nèi)容
- 點(diǎn)擊取消關(guān)閉 modal, 同時(shí)會調(diào)用名為 onClose 的回調(diào)
- 點(diǎn)擊確認(rèn)會調(diào)用名為 onConfirm 的回調(diào),并關(guān)閉 modal
- 點(diǎn)擊蒙層 mask 關(guān)閉 modal
- animate 字段可以開啟/關(guān)閉動畫
控制 modal 顯隱
修改
src/modal/index.jsx
import React from 'react';
import './index.css';
export default class Modal extends React.Component {
constructor(props) {
super(props)
}
render() {
// 通過父組件傳遞的 visible 控制顯隱
const { visible = true } = this.props
return visible &&
(
<div className='wrapper'>
<div className='modal'>
<div className='title'>標(biāo)題區(qū)</div>
<div className='content'>內(nèi)容區(qū)</div>
<div className='operator'>
<button className='close'>取消</button>
<button className='confirm'>確定</button>
</div>
</div>
<div className='mask'>mask</div>
</div>
)
}
}
修改
src/App.js, 通過一個(gè) Button 來控制 modal 的顯隱
import React, { Component, Fragment } from 'react';
import Modal from './modal';
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
visible: false,
}
}
showModal = () => {
this.setState({
visible: true,
});
}
render() {
const { visible } = this.state
return (
<Fragment>
<Modal visible={visible}/ >
<button onClick={() => this.showModal()} style={{
'background': '#4CA791',
'color': '#fff',
'border': 'none',
'width': 300,
'height': 50,
'fontSize': 30,
}}>切換顯隱</button>
</Fragment>
);
}
}
export default App;
標(biāo)題區(qū)和內(nèi)容區(qū)可自定義
修改
src/modal/index.jsx
import React from 'react';
import './index.css';
export default class Modal extends React.Component {
constructor(props) {
super(props)
}
render() {
// 通過父組件傳遞的 visible 控制顯隱
const { visible = true, title, children } = this.props
return visible &&
(
<div className='wrapper'>
<div className='modal'>
<div className='title'>{title}</div>
<div className='content'>{children}</div>
<div className='operator'>
<button className='close'>取消</button>
<button className='confirm'>確定</button>
</div>
</div>
<div className='mask'>mask</div>
</div>
)
}
}
修改
src/App.js, 從外部傳入自定義的 ‘title' 和 ‘content'
import React, { Component, Fragment } from 'react';
import Modal from './modal';
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
visible: false,
}
}
showModal = () => {
this.setState({
visible: true,
});
}
render() {
const { visible } = this.state
return (
<Fragment>
<Modal
visible={visible}
title='這是自定義的title'>
這是自定義的content
</Modal>
<button onClick={() => this.showModal()} style={{
'background': '#4CA791',
'color': '#fff',
'border': 'none',
'width': 300,
'height': 50,
'fontSize': 30,
}}>切換顯隱</button>
</Fragment>
);
}
}
export default App;
控制區(qū)功能及蒙層點(diǎn)擊功能
- 要實(shí)現(xiàn)點(diǎn)擊取消按鈕關(guān)閉 modal, 那么就需要在 modal 中維護(hù)一個(gè)狀態(tài),然后用這個(gè)狀態(tài)來控制 modal 的顯隱,好像可行
- 但是前面我們是通過父組件的 visible 控制 modal 的顯隱,似乎矛盾
- 要結(jié)合起來,只通過 state 來控制 modal 的顯隱,props 改變只會改變 state
修改
src/modal/index.jsx
import React from 'react';
import './index.css';
export default class Modal extends React.Component {
constructor(props) {
super(props)
this.state = {
visible: false
}
}
// 首次渲染使用父組件的狀態(tài)更新 modal 中的 visible 狀態(tài),只調(diào)用一次
componentDidMount() {
this.setState({
visible: this.props.visible
})
}
// 每次接收 props 就根據(jù)父組件的狀態(tài)更新 modal 中的 visible 狀態(tài),首次渲染不會調(diào)用
componentWillReceiveProps(props) {
this.setState({
visible: props.visible
})
}
handleClose = () => {
const { onClose } = this.props
onClose && onClose()
this.setState({
visible: false
})
}
handleConfirm = () => {
const { onConfirm } = this.props
onConfirm && onConfirm()
this.setState({
visible: false
})
}
handleMask = () => {
this.setState({
visible: false
})
}
render() {
// 通過父組件傳遞的 visible 控制顯隱
const { title, children } = this.props
const { visible = true } = this.state
return visible &&
(
<div className='wrapper'>
<div className='modal'>
<div className='title'>{title}</div>
<div className='content'>{children}</div>
<div className='operator'>
<button className='close' onClick={this.handleClose}>取消</button>
<button className='confirm' onClick={this.handleConfirm}>確定</button>
</div>
</div>
<div className='mask' onClick={this.handleMask}>mask</div>
</div>
)
}
}
修改
src/App.js, 從外部傳入自定義的onClose和onConfirm
import React, { Component, Fragment } from 'react';
import Modal from './modal';
import './App.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
visible: false,
}
}
showModal = () => {
this.setState({
visible: true,
});
}
onClose = () => {
console.log('onClose');
}
onConfirm = () => {
console.log('onConfirm');
}
render() {
const { visible } = this.state
return (
<Fragment>
<Modal
visible={visible}
title='這是自定義的title'
onClose={this.onClose}
onConfirm={this.onConfirm}
>
這是自定義的content
</Modal>
<button onClick={() => this.showModal()} style={{
'background': '#4CA791',
'color': '#fff',
'border': 'none',
'width': 300,
'height': 50,
'fontSize': 30,
}}>切換顯隱</button>
</Fragment>
);
}
}
export default App;
小編是一名前端工程師,建了一個(gè)“前端內(nèi)推群”,里面有BAT等大廠的HR,也有知名獵頭,但大部分是前端工程師。群里會不定期發(fā)布前端相關(guān)的學(xué)習(xí)資源。群里的大佬們團(tuán)隊(duì)缺人,也會在群里招人。也聯(lián)合一些組織不定期會舉辦一些活動。逢年過節(jié)會有紅包。歡迎大家加入,一起成長,目前群人數(shù)較多,已達(dá)上限,可以先加機(jī)器人微信,注明“加群目的”,機(jī)器人會拉你入群。
機(jī)器人二維碼.jpeg

React技術(shù)交流群.jpeg
