在前端开发中,弹出模态框是经常会碰到的,我们在项目中用到的有两种方式,一种是自己实现,一种是用react-bootstrap中的Modal组件
首先看看我们要实现的功能
image.png
点击弹出示例对话框 的时候,弹出模态框。
我们在react中会把这个弹出的模态框封装成一个组件,这样就可以实现重复应用。
主页代码如下:
import React, {Component } from 'react';
import PropTypes from 'prop-types';
import { Link,Button,ButtonToolbar} from 'react-bootstrap';
import DeleteBusiness from 'component/manage/business/DeleteBusiness';
import Util from 'util';
const propTypes = {
};
class Modal extends Component {
static propTypes={
}
constructor(props) {
super(props);
this.state = {
show:false,
};
Util.bindFunction([
'remove',
'getModalButtons',
'removeShow'
], this);
}
remove(){
this.setState({
show:true
});
}
getModalButtons(){
return [
<a href="javascript:;"
className="btn btn-sm btn-danger">确定删除</a>
]
}
/**
* 解散分组模态框展示
*/
removeShow(){
const {
show,
}=this.state;
if(show){
return(
<DeleteBusiness title={ "解散分组" }
buttons={ this.getModalButtons() }
onClickCloseButton={ () => this.setState({
show: false
}) } >
<form className="form-horizontal">
<div className="form-group">
<label className="col-md-3 text-right m-0">名字</label>
<div className="col-md-8">
<p className="text_gray m-0">jshd</p>
</div>
</div>
<div className="form-group">
<label className="col-md-3 control-label">密码确认</label>
<div className="col-md-8">
<input type="password" className="form-control" placeholder="请输入您的登录密码" ref="passwordInput"/>
</div>
</div>
</form>
</DeleteBusiness>
)
}else {
return null;
}
}
render(){
return(
<div id="page-container" className="page-container page-sidebar-fixed page-header-fixed">
<div id="content" className="content">
<div>
<p>点击按钮感受一下弹出的对话框。</p>
<Button
bsStyle="primary"
bsSize="large"
onClick={()=>this.remove()} >
弹出示例对话框
</Button>
</div>
</div>
{this.removeShow()}
</div>
)
}
}
Modal.propTypes = propTypes;
export default Modal;
主页的代码很简单,在state中定义这个模态框展示的show属性,默认是false不展示模态框,点击改变属性值,不作过多的介绍,主要是模态框的实现。
一.自己实现Modal模态框
代码如下:
import React, { Component } from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
import { VelocityTransitionGroup } from 'velocity-react';
import Util from 'util';
class DeleteBusiness extends Component {
static propTypes = {
title: PropTypes.string,
buttons: PropTypes.array,
onClickCloseButton: PropTypes.func
};
static defaultProps = {
buttons: [],
onClickCloseButton: () => {}
};
constructor(props) {
super(props);
Util.bindFunction([
'hideModal'
], this);
}
hideModal() {
$(this.popup).find('.fade.in').removeClass('in');
setTimeout(() => {
ReactDom.unmountComponentAtNode(this.popup);
document.body.removeChild(this.popup);
this.popup = null;
}, 300);
$('body').removeClass('modal-open')
}
componentWillMount() {
const body = $('body');
this.popup = document.createElement("span");
body.append(this.popup);
this.renderModal();
body.addClass('modal-open');
}
componentWillUnmount() {
this.hideModal();
}
renderModal() {
const {
title,
buttons,
children,
onClickCloseButton
} = this.props;
const modal = (
<div>
<div className="modal-backdrop fade"></div>
<div className="modal fade">
<div className="modal-dialog ">
<div className="modal-content">
<div className="modal-header">
<a href="javascript:;"
onClick={ onClickCloseButton }
className="close btn btn-xs btn-icon btn-circle btn-danger m-0"><i className="fa fa-times"></i></a>
<h4 className="modal-title">{ title }</h4>
</div>
<div className="modal-body">
{ children }
</div>
<div className="modal-footer">
{ buttons.map((btn, index) => React.cloneElement(btn, {
key: ['PageModal', 'button', index].join('-')
})) }
</div>
</div>
</div>
</div>
</div>
);
ReactDom.render(modal, this.popup, () => {
const ls = $(this.popup).find('.fade').show();
setTimeout(() => ls.addClass('in'), 10)
});
}
render() {
return null
}
}
export default DeleteBusiness;
二.使用react-bootstrap中的Modal组件
代码如下:
import React, { Component } from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
import {Modal,Button} from 'react-bootstrap';
import Util from 'util';
class DeleteBusiness extends Component {
static propTypes = {
title: PropTypes.string,
buttons: PropTypes.array,
onClickCloseButton: PropTypes.func,
removeShowModal:PropTypes.string
};
static defaultProps = {
buttons: [],
onClickCloseButton: () => {}
};
constructor(props) {
super(props);
Util.bindFunction([
'hideModal'
], this);
}
hideModal() {
$(this.popup).find('.fade.in').removeClass('in');
setTimeout(() => {
ReactDom.unmountComponentAtNode(this.popup);
document.body.removeChild(this.popup);
this.popup = null;
}, 300);
$('body').removeClass('modal-open')
}
componentWillMount() {
const body = $('body');
this.popup = document.createElement("span");
body.append(this.popup);
body.addClass('modal-open');
}
componentWillUnmount() {
this.hideModal();
}
render() {
const {
title,
buttons,
children,
onClickCloseButton,
removeShowModal
} = this.props;
return(
<Modal show={removeShowModal} onHide={this.props.onClickCloseButton}>
<Modal.Header closeButton>
<Modal.Title>{title}</Modal.Title>
</Modal.Header>
<Modal.Body>
{ children }
</Modal.Body>
<Modal.Footer>
{ buttons.map((btn, index) => React.cloneElement(btn, {
key: ['PageModal', 'button', index].join('-')
})) }
</Modal.Footer>
</Modal>
)
}
}
export default DeleteBusiness;
此时是将父组件是否显示模态框的state传过来的,所以主页代码调用模态框的组件时需要加个prop,
<DeleteBusiness title={ "解散分组" }
buttons={ this.getModalButtons() }
onClickCloseButton={ () => this.setState({
show: false
}) }
removeShowModal={this.state.show}>
<form className="form-horizontal">
<div className="form-group">
<label className="col-md-3 text-right m-0">名字</label>
<div className="col-md-8">
<p className="text_gray m-0">jshd</p>
</div>
</div>
<div className="form-group">
<label className="col-md-3 control-label">密码确认</label>
<div className="col-md-8">
<input type="password" className="form-control" placeholder="请输入您的登录密码" ref="passwordInput"/>
</div>
</div>
</form>
</DeleteBusiness>