• React封装公共函数:弹窗


    需求分析

    很多时候我们需要通过弹窗/对话框来完成交互,因此这个公共的弹窗组件需要实现以下功能:

    • 组件动态地传入弹窗的标题和内容
    • 点击确定和取消按钮之后,执行组件传入的回调函数

    样式布局

    JSX代码如下:(通过 styled-components 开发样式)

    const JSXdom = (
        <div>
            <Mask />
            <ModalWrapper>
            	<ModalContent>
            		<p className="title">{title}</p>
            		<div className="content">{tips}</div>
            	<BtnGroup >
            		<div
                    	className="btn left"
                    	onClick={() => this.onCancel(handleCancel)}
                    >取消</div>
                    <div
                    	className="btn right"
                    	onClick={() => this.onOk(handleOk)}
                    >确定</div>
            	</BtnGroup>
            </ModalContent>
            </ModalWrapper>
        </div>
    )
    

    首先我们需要一个遮住层Mask作为背景,实现页面背景变暗的效果

    export const Mask = styled.div`
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.65);
      z-index: 1000;
    `
    

    然后用过绝对定位 + transform 实现弹窗的水平垂直居中

    并对标题、内容、确认和取消按钮进行简单的布局

    export const ModalWrapper = styled.div`
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1000;
    `
    
    export const ModalContent = styled.div`
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      padding: 20px 20px 0 20px;
       60%;
      background-color: #fff;
      border-radius: 4px;
      text-align: center;
      .title {
        font-size: 18px;
        margin-bottom: 15px;
      }
      .content {
         100%;
        font-size: 14px;
        line-height: 20px;
        margin-bottom: 15px;
        word-wrap: break-word; 
      }
    `
    
    export const BtnGroup = styled.div`
      display: flex;
      align-items: center;
      text-align: center;
      font-size: 14px;
      .btn {
        flex: 1;
        line-height: 22px;
        padding: 10px 0;
        border-top: 1px solid whitesmoke;
        background-color: #fff;
        &.left {
          border-right: 1px solid whitesmoke;
        }
      }
    `
    

    核心函数

    核心函数的职责如下:

    1. 创建一个空的div节点(createElement)
    2. 将上述JSX渲染到div节点上(ReactDom.render)
    3. 将div节点挂载到body上(appendChild)

    代码如下:

    success() {
    	this.dom = document.createElement('div')
        
        const JSXDOM = ()
        
        ReactDom.render(JSXDOM,this.dom)
        document.dody.appendChild(this.dom)
    }
    

    这样,我们就成功将弹窗渲染到页面上了

    回调函数

    当用户点击确定或取消时,我们必须将控制权交还给 调用弹窗的组件,由组件来执行后续的操作

    因此,success函数需要接收 handleOk 和 handleCancel 这两个函数作为参数

    为了使得弹窗消失,我们还需要再封装 onOk 和 onCancel 函数,让他们去调用组件的回调函数,并且清除this.dom

    首先将清除dom的任务封装成一个辅助函数 removeDom

    removeDom() {
        this.dom && this.dom.remove()
        /* 
        	写法等同于
        	if(this.dom){
        		this.dom.remove()
        	}
        */
    }
    

    然后编写onOk和onCancel函数

    onOk(handleOk) {
    	(handleOk instanceof Function) && handleOk()
    	this.removeDom()
    }
    
    onCancel (handleCancel) {
        (handleCancel instanceof Function) && handleCancel()
        this.removeDom()
    }
    

    完整的代码如下:

    import React from 'react'
    import ReactDOM from 'react-dom'
    import {
        Mask,
        ModalWrapper,
        ModalContent,
        BtnGroup
    } from './style'
     
    export default {
        dom: null,
     
        success ({title,tips,handleOk,handleCancel}) {
          this.removeDom()
    
          this.dom = document.createElement('div')
    
          const JSXdom = (
            <div>
                <Mask />
                <ModalWrapper>
                    <ModalContent>
                        <p className="title">{title}</p>
                        <div className="content">{tips}</div>
                        <BtnGroup >
                            <div
                                className="btn left"
                                onClick={() => this.onCancel(handleCancel)}
                            >取消</div>
                            <div
                                className="btn right"
                                onClick={() => this.onOk(handleOk)}
                            >确定</div>
                        </BtnGroup>
                    </ModalContent>
                </ModalWrapper>
            </div>
          )
    
          ReactDOM.render(JSXdom,this.dom)
          document.body.appendChild(this.dom)
        },
    
        onCancel (handleCancel) {
          (handleCancel instanceof Function) && handleCancel();
          this.removeDom()
        },
    
        onOk (handleOk) {
          (handleOk instanceof Function) && handleOk();
          this.removeDom()
        },
    
        removeDom() {
          this.dom && this.dom.remove()
        }
    }
    

    组件调用

    import Modal from './xxx.js'
    
    class W extends from Component {
        render(){
            return(
                <div onClick={this.handleClick}>点击</div>
            )
        }
        
        handleClick() {
            Modal.success({
                title: '标题',
                tips: '测试弹窗',
                handleOk: () => {
                    console.log('Ok')
                },
                handleCancel: () => {
                    console.log('Cancel')
                }
            })
        }
    }
    

    注意:组件传入的 hanldleOk 和 handleCancel 最好使用箭头函数的方式来定义

    这样才能确保函数在执行的时候,this的指向为当前组件

  • 相关阅读:
    通讯总线 | 串口
    shell | 命令实用汇集
    编码 | 宏定义格式化日志信息
    shell | 脚本传参
    注释 | 代码注释原则
    GCC编译优化选项介绍
    shell | 已知进程查找命令
    网络 | ifconfig 配置 IP 掩码 网关
    Makefile | 使用eclipse软件自动生成Makefile文件
    VIO系统的IMU与相机时间偏差标定
  • 原文地址:https://www.cnblogs.com/baebae996/p/14397689.html
Copyright © 2020-2023  润新知