如何用React寫一個Modal元件

PsChina發表於2019-04-08

要求: 元件講究的是複用性,和可移植性。

可複用:就是要做到元件邏輯功能和業務邏輯功能互不影響也就是所謂的解藕。

可移植:就是要做到軟體(元件)與系統無關,也就是沒有外部依賴。

純函式元件也稱無狀態元件在這裡得到了很好的應用。

最簡單的純函式元件

const text = props=><span>{props.text}</span>
複製程式碼

思路: Modal 的實現思路極其簡單

const Modal = props=>props.visibale ? <MyModal/> : null
複製程式碼

資料採用從父元件接收 props 的方式獲取而不採用 state 能實現 Modal 元件檢視與資料的分離,除了耦合從而達到了可複用的目的。

只需將 props 中的

title (標題)

content (內容)

onOk (確認事件)

onCancel (取消事件)

按照一定的邏輯放置在 Modal 中即可

(當然還有其他的引數比如 width height 就不一一列舉)

以下是我的實現:


實現:

Modal.jsx 檔案

import React from 'react'
import './Modal.css'

const Modal = props => props.visible ? (<div className="modal-box" style={{backgroundColor:`rgba(0, 0, 0, ${props.opacity})`}}>
<div className="modal-content" style={{width:props.width,height:props.height}}>
    <div className={props.titleClass}>{props.title}</div>
    <div className={props.contentClass}>{props.content}</div>
    <div className={props.footerClass}>
        <div onClick={props.onOk} className={props.okClass}>{props.conFirmText}</div>
        <div onClick={props.onCancel} className={props.cancelClass}>{props.cancelText}</div>
    </div>
</div>
</div>) : null

const noop = _=> undefined

Modal.defaultProps = {
    onOk: noop,
    onCancel: noop,
    conFirmText: '確定',
    cancelText: '取消',
    titleClass: 'modal-title',
    contentClass: 'modal-text',
    footerClass: 'modal-footer',
    okClass: 'modal-confirm',
    cancelClass: 'modal-cancel',
    height:'auto',
    width:'400px',
    opacity: 0.6
}

export default Modal
複製程式碼

Modal.css 檔案

.modal-box {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 9999;
    /* background-color: rgba(0, 0, 0, 0.8); */
    display: flex;
    justify-content: center;
    align-items: center;
}

.modal-content {
    position: relative;
    min-width: 400px;
    background-color: white;
    padding: 40px;
    box-sizing: border-box;
}

.modal-title{
    font-weight: bold;
    font-size: 22px
}

.modal-text {
    font-size: 16px;
}

.modal-footer {
    
}

.modal-confirm,.modal-cancel {
    width: 100px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    cursor: pointer;
    position: absolute;
    bottom: 40px;
}

.modal-confirm {
    left: 40px;
}

.modal-cancel {
    right: 40px;
}
複製程式碼

使用方式:

屬性 說明 預設值 型別
onOk 點選確定的回撥函式 noop function
onCancel 點選取消的回撥函式 noop function
conFirmText 確定按鈕自定義文字 '確定' string
cancelText 取消按鈕自定義文字 '取消' string
titleClass 對話方塊 title 自定義樣式 'modal-title' string
contentClass 對話方塊內容自定義樣式 'modal-text' string
footerClass 對話方塊確定取消按鈕容器自定義樣式 'modal-footer string
okClass 對話方塊確定按鈕自定義樣式 'modal-confirm' string
cancelClass 對話方塊取消按鈕自定義樣式 'modal-cancel' string
height 對話方塊寬度 'auto' string
width 對話方塊高度 '400px' string
opacity 對話方塊透明度 0.6 nunmber

demo.js 檔案

import React, { Component } from 'react';
import './App.css';
import Modal from './Modal/Modal.jsx'
class App extends Component {
  constructor(){
    super()
    this.state = {
      title: 'React Modal',
      content: '歡迎使用!',
      visible: false
    }
  }
  openModal(){
    this.setState({
      visible: true
    })
  }
  onOk(){
    this.setState({
      visible:false
    })
  }
  onCancel(){
    this.setState({
      visible:false
    })
  }
  render() {
    return (
      <div className="App">
        <div onClick={this.openModal.bind(this)}>開啟彈窗</div>
        <Modal 
        width={'600px'}
        height={'600px'}
        visible={this.state.visible}
        title={this.state.title} 
        content={this.state.content} 
        onOk={this.onOk.bind(this)} 
        opacit={0.66}
        onCancel={this.onCancel.bind(this)}/>
      </div>
    );
  }
}

export default App;
複製程式碼

原文連結及原始碼

相關文章