react中使用Modal模態(tài)框

在前端開發(fā)中,彈出模態(tài)框是經(jīng)常會碰到的戴质,我們在項目中用到的有兩種方式虑稼,一種是自己實現(xiàn)魂奥,一種是用react-bootstrap中的Modal組件
首先看看我們要實現(xiàn)的功能

image.png

點擊彈出示例對話框 的時候讨跟,彈出模態(tài)框纪他。
我們在react中會把這個彈出的模態(tài)框封裝成一個組件,這樣就可以實現(xiàn)重復(fù)應(yīng)用晾匠。
主頁代碼如下:

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>

        ]
    }
    /**
     * 解散分組模態(tài)框展示
     */
    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">密碼確認(rèn)</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中定義這個模態(tài)框展示的show屬性凉馆,默認(rèn)是false不展示模態(tài)框薪寓,點擊改變屬性值亡资,不作過多的介紹,主要是模態(tài)框的實現(xiàn)向叉。

一.自己實現(xiàn)Modal模態(tài)框

代碼如下:

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;

此時是將父組件是否顯示模態(tài)框的state傳過來的锥腻,所以主頁代碼調(diào)用模態(tài)框的組件時需要加個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">密碼確認(rèn)</label>
                            <div className="col-md-8">
                                <input type="password" className="form-control" placeholder="請輸入您的登錄密碼" ref="passwordInput"/>
                            </div>
                        </div>
                    </form>
                </DeleteBusiness>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末植康,一起剝皮案震驚了整個濱河市旷太,隨后出現(xiàn)的幾起案子展懈,更是在濱河造成了極大的恐慌销睁,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件存崖,死亡現(xiàn)場離奇詭異冻记,居然都是意外死亡,警方通過查閱死者的電腦和手機来惧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門冗栗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人供搀,你說我怎么就攤上這事隅居。” “怎么了葛虐?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵胎源,是天一觀的道長。 經(jīng)常有香客問我屿脐,道長涕蚤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任的诵,我火速辦了婚禮万栅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘西疤。我一直安慰自己烦粒,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布代赁。 她就那樣靜靜地躺著扰她,像睡著了一般。 火紅的嫁衣襯著肌膚如雪管跺。 梳的紋絲不亂的頭發(fā)上义黎,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音豁跑,去河邊找鬼廉涕。 笑死泻云,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的狐蜕。 我是一名探鬼主播宠纯,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼层释!你這毒婦竟也來了婆瓜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤贡羔,失蹤者是張志新(化名)和其女友劉穎窄陡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體助币,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡蓬网,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了楣嘁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磅轻。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逐虚,靈堂內(nèi)的尸體忽然破棺而出聋溜,到底是詐尸還是另有隱情,我是刑警寧澤叭爱,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布撮躁,位于F島的核電站,受9級特大地震影響涤伐,放射性物質(zhì)發(fā)生泄漏馒胆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一凝果、第九天 我趴在偏房一處隱蔽的房頂上張望祝迂。 院中可真熱鬧,春花似錦器净、人聲如沸型雳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纠俭。三九已至,卻和暖如春浪慌,著一層夾襖步出監(jiān)牢的瞬間冤荆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工权纤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钓简,地道東北人乌妒。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像外邓,于是被迫代替她去往敵國和親撤蚊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,071評論 25 707
  • 今天上午組內(nèi)小朋友們談到 React 實踐损话,提到 React 模態(tài)框(彈窗)的使用侦啸。我發(fā)現(xiàn)很多一些 React 開...
    LucasHC閱讀 1,860評論 0 17
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件丧枪、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評論 4 62
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議光涂。它實...
    香橙柚子閱讀 23,848評論 8 183
  • 對真核細(xì)胞祖先的追尋進入到了一個可怕的困境之中『阑澹可能存在一個初級的中間體顶捷,一個擁有細(xì)胞核卻沒有線粒體的缺失的一環(huán)的...
    魚骨頭段閱讀 2,392評論 1 50