手把手帶你實現React的Modal組件

1、背景

衆所周知,產品經理有三寶:彈窗、浮層和引導。身爲一個程序員,尤爲是前端工程師不得不面向產品編程,因爲原型圖上滿滿的彈窗,逼迫咱們不得不封裝一個彈窗組件來應付產品的需求javascript

2、須要實現的Modal組件的API

一、經過傳入一個visible來控制彈框的顯示與隱藏,數據類型爲boolean
二、經過傳入一個title來設置彈框的標題,數據類型爲string
三、經過傳入一個onOk函數來設置彈框確認按鈕的操做,數據類型爲function
四、經過傳入一個onCancel函數來設置彈框關閉取消按鈕的操做,數據類型爲function
五、經過傳入一個children來設置彈框主體內容,數據類型爲elementcss

3、Modal組件具體代碼實現

import React, { Component } from 'react'
import Button from '../Button/Button'
import PropTypes from 'prop-types'
import './GYModal.less'
export default class GYModal extends Component {
  static propTypes = {
    visible: PropTypes.bool,
    title: PropTypes.string,
    onOk: PropTypes.func,
    onCancel: PropTypes.func,
    children: PropTypes.element
  }
  static defaultProps = {
    visible: false,
    title: '標題',
    onOk: () => {},
    onCancel: () => {}
  }
  render () {
    const {
       visible,
       title,
       children,
       onOk,
       onCancel
    } = this.props,
    show = { zIndex: 2000, opacity: 1 },
    hide = { zIndex: -1, opacity: 0 },
    contShow = { width: '600px', height: '600px' },
    contHide = { width: '0px', height: '0px' }
    return (
      <div className="gy-modalContainer" style={ visible ? show : hide }> <div className="mask" onClick={onCancel}></div> <div className="innerContent" style={ visible ? contShow : contHide }> <div className="innerContent-header"> <div className="innerContent-title">{title}</div> </div> <div className="innerContent-center"> {children} </div> <div className="innerContent-footer"> <Button type='cancel' onClick={onCancel}>取消</Button> <Button type='primary' onClick={onOk}>肯定</Button> </div> </div> </div>
    )
  }}複製代碼

注意:這裏在打開和關閉彈框時,增長了css3動畫過濾效果。一開始爲了實現動畫過渡效果,我首先想到的是經過改變display: none到display: block,而且設置transition: all .3s ease來實現過濾動畫效果,後來發現根本沒有效果,緣由是transition是不支持display屬性的過渡的,固然你能夠經過js的settimeout來實現,這邊就直接用css3來實現動畫過渡效果了。Modal組件最外層容器經過改變z-index和opacity來實現過渡動畫效果,而Modal組件的彈框內容部分主要是經過改變彈框的width和height來實現過渡動畫效果的,這兩個部分的動畫效果都是由visible來控制的。前端

.gy-modalContainer{
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 1;
  transition: all .3s cubic-bezier(.075, .82, .165, 1);
  z-index: -1;
  .mask{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    background-color: rgba(0,0,0,.3);
  }
  .innerContent{
    position: absolute;
    left: 50%;
    top: 50%;
    width: 600px;
    height: 600px;
    height: auto;
    z-index: 3;
    background-color: #FFFFFF;
    transition: all .3s cubic-bezier(.075, .82, .165, 1);
    transform-origin: 75.5px 221.5px 0px;
    transform: translate(-50%,-50%);
    border-radius: 4px;
    .innerContent-header{
      padding: 13px 16px;
      border-radius: 4px 4px 0 0;
      background: #fff;
      color: rgba(0,0,0,.65);
      border-bottom: 1px solid #e9e9e9;
      .innerContent-title{
        margin: 0;
        font-size: 14px;
        line-height: 21px;
        font-weight: 500;
        color: rgba(0,0,0,.85);
      }
    }
    .innerContent-center{
      padding: 16px;
      font-size: 12px;
      line-height: 1.5;
    }
    .innerContent-footer{
      border-top: 1px solid #e9e9e9;
      padding: 10px 16px 10px 10px;
      border-radius: 0 0 4px 4px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }
  }}複製代碼


4、使用Modal組件

如下是render函數中的代碼java


如下是展現效果react

相關文章
相關標籤/搜索