zoukankan      html  css  js  c++  java
  • 封装React AntD的dialog弹窗组件

    前一段时间分享了基于vue和element所封装的弹窗组件(封装Vue Element的dialog弹窗组件),今天就来分享一个基于react和antD所封装的弹窗组件,反正所使用的技术还是那个技术,情况还是那个情况。只是基于vue所封装的弹窗组件和基于react所封装的弹窗组件还是有很大差别的。一样的是封装的思想和思路,不一样的是实现的技术。

    至于所用到的技术,还是跟之前分享的有关react组件所用到的技术差不多,无非就是react hooks、函数式组件等。实现思路的话,还是在父组件中打开弹窗,关闭弹窗的操作就交给所封装的弹窗组件,不采用那种所谓的给子组件传一个关闭弹窗的函数,然后让子组件来触发,触发后再由父组件将关闭弹窗的参数传给子组件。这种实现思路可以是可以,就是太绕了,实现起来也麻烦不是?而且每次使用这个弹窗组件时,还得在每个父组件中都写一个关闭弹窗的方法,不累吗?封装的目的是什么?一是统一样式和功能,二是高复用性,三是少写代码,降低开发量,提高开发效率。在我们国家不是有一句很流行的话吗?“让专业的人干专业的事儿”,比如让姚明出任篮协主席,让那个所谓“不懂球的胖子”出任乒协主席,就是这个理儿。

    当然有人可能会说如果将关闭弹窗的操作只交给弹窗来做的话,那么万一要在关闭弹窗后再执行某个操作呢,比如弹窗中嵌套了表单组件,如果有表单正则验证没通过,会在表单输入框下边有一个红色的文字提示,此时若关闭弹窗,下次再打开弹窗时会发现那个红色的文字提示还在,这个问题咋解决?总不能在关闭弹窗的函数中加入一个重置表单的方法吧,那如果还有其他需求呢,是不是也要在关闭弹窗的函数中再加入一个方法呢?如果其他需求不需要这样的方法呢?很好,有这样的疑问,说明你考虑问题很全面,哈哈哈哈哈哈,且这样的需求也是实实在在存在的,但依然有很好的解决办法,那就是充分利用弹窗关闭后的回调方法。

    关于弹窗关闭后的回调方法,antD和element的弹窗组件都有这个方法,只是element的弹窗组件在关闭后有两个回调:

    • close:Dialog关闭的回调

    • closed:Dialog关闭动画结束时的回调

    对于这两个回调,我都拿来试了一把,发现在一般情况下它俩的效果一样,那么官方对第二个回调给的解释是关闭动画结束时的回调,我就有点懵逼了。有兴趣的大佬或已经尝试过的大神别喷我,您就指着我的鼻子,居高临下地告诉我该怎么玩这个就可以了,我会虚心接受的。悄没声地告诉你:element的弹窗组件在关闭的回调中加入重置表单的功能,貌似就无法获取到已修改的表单的值(我是在封装的弹窗组件中嵌套的自己封装的form表单组件,发现在弹窗的关闭回调中去调用嵌套的form组件的重置方法后,获取到的修改的表单的值就变成了上次回显的表单的值,最后我只能把重置表单的功能放在了form组件的mounted生命周期函数中才得以实现。具体实现请移步封装Vue Element的form表单组件),但是antD的弹窗组件就不存在这个问题。

    antD在关闭弹窗后也给了一个回调afterClose,官方的解释是Modal完全关闭后的回调,但人家就只给了这一个关闭后的回调。好吧,就这个回调已经足够我们实现我们的需求了。我们把那些需要在关闭弹窗后再做的一些事情都放在这个回调中,然后把这个回调从父组件再传给所封装的弹窗子组件就完事了。如果你不传,代表你没有这方面的需求,对弹窗的正常工作又没有丝毫的影响,这岂不是很香吗?

    说了这么多,光说不练假把式,那就来看具体实现呗。

    照例还是先来张效果图:

    1、所封装的弹窗组件dialog.js

    import React, { useState, useImperativeHandle } from 'react'
    import PropTypes from 'prop-types'
    import { Modal } from 'antd';
    
    let ok = () => {};
    const DialogCom = ({btnTxt = ['取消', '确定'], children, cRef, autoClose = true, ...reset}) => {
      const [visible, setVisible] = useState(false);
    
      const open = cb => {
        setVisible(true);
        ok = cb;
      }
    
      useImperativeHandle(cRef, () => ({
        open: cb => open(cb),
      }));
    
      const handleCancel = () => {
        setVisible(false);
      }
    
      const handleOk = () => {
        autoClose && setVisible(false);
        ok(handleCancel);
      }
    
      return <Modal
        {...reset}
        maskClosable={false}
        visible={visible}
        onOk={handleOk}
        onCancel={handleCancel}
        okText={btnTxt[1]}
        cancelText={btnTxt[0]}
      >
        {children}
      </Modal>
    }
    
    DialogCom.propTypes = {
      btnTxt: PropTypes.array,
      children: PropTypes.any.isRequired,
      cRef: PropTypes.object.isRequired,
      autoClose: PropTypes.bool,
    }
    
    export default DialogCom
    

    以上代码中的具体实现思路这里就不再做过多的介绍了,可以移步封装Vue Element的dialog弹窗组件这里。封装Vue Element的dialog弹窗组件这篇博文已经对实现的思路做了详细的介绍了。

    2、使用方法:

    import React, { useRef } from 'react'
    import { Button } from 'antd';
    import Dialog from './dialog'
    
    const DialogDemo = () => {
      const childRef = useRef();
    
      const open = () => {
        childRef.current.open(cancel => {
          // cancel();
          console.log('打开')
        });
      }
    
      const resetForm = () => {
        console.log('重置表单')
      }
    
      const config = {
        title: '提示',
        btnTxt: ['关闭', '提交'],
        centered: true,
         '400px',
        afterClose: resetForm, // Modal完全关闭后的回调
      }
    
      return <>
        <Button type="primary" onClick={open}>打开弹窗</Button>
        <Dialog {...config} cRef={childRef}>
          <p>我是弹窗</p>
          <p>我是弹窗</p>
        </Dialog>
      </>
    }
    
    export default DialogDemo
    

    使用方法中的代码这里也不再做介绍了,封装Vue Element的dialog弹窗组件这篇博文也介绍的很详细了。

    最后还是再贴一下本次封装所用到的各个包的版本:

    react: 16.8.6,

    react-dom: 16.8.6,

    react-router-dom: 5.0.0,

    antd: 4.3.5,

    @babel/core: 7.4.4,

    babel-loader: 8.0.5

  • 相关阅读:
    Qt中暂停线程的执行(主线程和工作线程共用一把锁,一旦主线程将它锁上,工作线程就无法运行了,这也是一个办法)
    罗振宇 知识就是力量:怎样逼自己成为一个上进的人
    GammaRay 是一个允许你查看 Qt 应用程序甚至在某种程度上修改它的独特应用,可谓是 Debugger 的良好补充
    VSCode高效开发插件
    微软白板Excel xls列号数字转字母
    如何渡过中年危机
    增量数据同步中间件
    N位N进制里有多少个N
    Orchard Core学习一
    Consul做服务发现
  • 原文地址:https://www.cnblogs.com/tnnyang/p/13645327.html
Copyright © 2011-2022 走看看