弹窗插件

223 阅读1分钟

来一个偷懒的弹窗组件react的。
先来讲一下如何使用,

import React, {Component} from 'react';
import {Model} from "@components/HOC"
// 将封装好的弹窗组件引进来,打上@Model即可将当前文件作为弹窗的内容,去掉@Model则该文件只是一个普通的组件页面内容
@Model
export default class test extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div>
        弹窗需要显示的内容
      </div>

    )
  }
}

封装弹窗的代码如下所示:

import React, {Component} from 'react';
import {Modal, Button, Form} from 'antd';
import ReactDOM from 'react-dom'  //引入react-dom对象,从而可以使用render()函数渲染页面
import "@styles/Dialog/MaapDialog.less";
export const Model = WrappedComponent => {
    let container;
    let refForm= React.createRef()
    let refDom=null;
    let objct=null;
  function ModelComponent(props) {
      // console.log(props);
      // 弹窗的title----title
    // 弹窗取消回调函数----onClose
    // 弹窗确定回调函数
    // 弹窗是否显示分割线----showBr
    // 弹窗是否显示右上角的X关闭按钮----closable
    // 弹窗的特别class----className
    // 弹窗是否显示底部按钮----clearFooter/footerBtn
    // 弹窗确定按钮的文案----ConfirmText
    // 弹窗取消按钮的文案----CancelText
    // 其他参数
    let {title, onCancel, onOk, showTitleBr,showBr, closable=false, className, clearFooter, ConfirmText, CancelText,hideConfirm,hideCancel,footerBtn,disabled=true, ...others} = props;
    function handleComfirm(){//决定母页面点击还是子页面点击  如果母页面传事件则覆盖子页面的点击事件
      if (refForm.current) {
        const {current}=refForm
        checkForm(current,(fieldsValue)=>{
          return onOk?onOk(fieldsValue):refForm.current.onOk(fieldsValue)
        });
      }else{
        return onOk?onOk(objct):refDom.onOk(refDom)
      }
    }
    function handleClose(){//取消按钮
      if(!onCancel&&(!(refForm.current&&refForm.current.onCancel)||!(refDom&&refDom.onCancel))){
        closeHandle();
        return;
      }
      if (refForm.current) {
        onCancel?onCancel():refForm.current.onCancel();
      }else{
        onCancel?onCancel():refDom.onCancel();
      }
    }
    function onChange(val) {
        objct=val
    }
    function checkForm(dom,callback) {//检测是否符合规则
      if(!dom.validateFields){
        callback(objct);
        return;
      } 
      dom.validateFields((err, fieldsValue) => {
        if (err) return;
        callback(fieldsValue)
      })
    }
    function changeDisabled(flag=false) {
            ReactDOM.render(<ModelComponent {...props}  disabled={flag} onClose={closeHandle}/>, container);
    }

    let DefaultFooterBtn =[
      <Button key="back" type="primary" onClick={() => handleClose()}>
        {CancelText || '取消'}
      </Button>,
      <Button key="submit" type="primary"  disabled={disabled} className="MaapDialog__comfirm" onClick={()=>handleComfirm()}>
        {ConfirmText || '确定'}
      </Button>
    ];

    if(hideConfirm) DefaultFooterBtn.splice(1, 1);
    if(hideCancel) DefaultFooterBtn.splice(0, 1);

    return  (
        <Modal visible={true} title={title||' '} footer={footerBtn==='kong'? null: (footerBtn||DefaultFooterBtn)} okButtonProps={{disabled}}
               className={`MaapDialog ${className || ''} ${clearFooter ? 'clearFooter' : ''} ${showBr ? '' : 'showBr'} ${showTitleBr ? '' : 'showTitleBr'}`}
               onCancel={() => handleClose()} closable={closable}
               {...others}
        >
            <WrappedComponent  changeDisabled={changeDisabled}  onChange={onChange} {...others}   refForm={refForm}  onRef={(node) => refDom = node}/>
        </Modal>
    );
  }
  function closeHandle() {
    ReactDOM.unmountComponentAtNode(container);
    document.body.removeChild(container);
    ModelComponent.params={disabled:false};
    container = null;
  }
  //通过调用show方法即可调用该弹窗组件,并传参
  ModelComponent.show = params => {
    container = document.createElement("div");
    document.body.appendChild(container);
    if(ModelComponent.params) params=Object.assign(ModelComponent.params,params);
    ReactDOM.render(<ModelComponent {...params} onClose={closeHandle}/>, container);
  }
  ModelComponent.hide = params => {
    closeHandle()
  }
  return ModelComponent;
}