antd中封装Modal的几种方式

1 利用Modal.method.

特点:无需考虑visible。抛出数据方便

基本使用:

1新建一个Dilaog.js。核心内容是创建一个Modal

import {Form,Modal,Input} from "antd"
import React from "react"
import {Button} from "antd"

function CreatModal(props) {
    const Content = ({formRef}) => {
        const [form] = Form.useForm()
        const onFinish = (values) => {
            console.log('Success:', values);
        };
        const onFinishFailed = (errorInfo) => {
            console.log('Failed:', errorInfo);
        };
        return (
            <Form 
                form={form} 
                ref={formRef}  
                onFinish={onFinish}
                onFinishFailed={onFinishFailed}
            >
                <Form.Item label="姓名" name="name" rules={[{ required: true, message: 'Please input your username!' }]}>
                    <Input style={{ width: 200 }} />
                </Form.Item>
                <Form.Item label="球队" name="team" rules={[{ required: true, message: 'Please input your username!' }]}>
                    <Input style={{ width: 200 }} />
                </Form.Item>
                <Form.Item style={{ width: 200 }}>
                    <Button type="primary" htmlType="submit">
                     Submit
                    </Button>
                </Form.Item>
            </Form>
        )
    }
    // content里面存放表单
    return new Promise((openSuccess,openError) => {
        const formRef = React.createRef();
        Modal.confirm({
            title: props.title,
            content: <Content formRef={formRef} />,
            okText: '确定',
            cancelText: '取消',
            onOk() {
                return new Promise((resolve,reject) => {
                    formRef.current.validateFields().then(values =>{
                        // 获取表单数据,在这里进行异步操作
                        resolve()
                        openSuccess(123)
                    }).catch(err=>{
                        reject()
                        openError(123)
                    })
                
                })
            }
        })
    })
}
export default modalOpen;

2 在父组件中引入该函数

import { Component,useRef } from "react"
import CreateMpdal from '../components/CreateMpdal.js'
import {Button} from "antd"
function Detail(){
    const openModal= async() => {
        let data={
            title:"我是标题"
        }
      let res= await CreateMpdal(data); 
      console.log("res:",res) //这里会抛出123
    }
    
    return(
       <div>
           <Button onClick={createData}> dia</Button>
         
       </div> 

    )
}

export default Detail

 2 利用useRef获取Modal组件的ref,直接操作其显示和隐藏。

特点:需要再Modal内部引入一个visible变量。数据抛出需要通过在组件中传递一个props函数来在父组件中接收。相对方法一稍显复杂。但是通过ref引用来控制Modal内部的隐藏和显示,避免在父组件内部再申明一个visible的state

具体用法:

import React, { useState, forwardRef, useImperativeHandle,useRef } from 'react'
import {Modal} from "antd"
function Dialog(props, ref) {
  const { onSuccess, renderBtn = <span>aaa</span>, item = {},successFn } = props
  const [visible, setVisible] = useState(false)

  // modal的显示与隐藏
  const showModal = () => {
    setVisible(true)
  }
  const hideModal = () => {
    setVisible(false)
  }
  
  useImperativeHandle(ref, () => ({
    showModelRef: showModal,
    hideModelRef: hideModal
  }))

  const handleClose = () => {
    hideModal();
    let num=100;
    successFn(num)  //注意这里。successFn是父组件的方法,这里把num的值传出去
  }
  return (   
      <Modal
        width={670}
        footer={null}
        visible={visible}
        centered={true}
        maskClosable={false}
        onCancel={handleClose}
        destroyOnClose={true}
      >     
       <h1>这是测试一</h1>
       <h2>这是测试一</h2>
       <h3>这是测试一</h3>
       <h4>这是测试一</h4>
      </Modal>
  )
}

export default forwardRef(Dialog)

父组件代码:

import { Component,useRef } from "react"
import Dialog from '../components/dialog.js'
import {Button} from "antd"

function Home(){

    const successFuc=(data)=>{
        console.log("success--",data)
    }
    const dialogRef = useRef()
    const test=()=>{
        console.log("dialogRef:",dialogRef)
        dialogRef.current.showModelRef(true)
    }
    return(
       <div>
            <Button type="primary" onClick={test}>home--点击</Button>
            <Dialog successFn={successFuc} ref={dialogRef} ></Dialog>
       </div> 

    )
}

export default Home

3 还是利用高阶组件的思想。我们把组件的属性通过prop传递给modal,再通过把函数通过props传来抛出modal内部的数据。

(1)新建一个wrap.js

import React from 'react';
import ReactDOM from 'react-dom';

const wrapper = (component) => {
  // 销毁组件
  const destoryDialog = (element) => {
    const unmountResult = ReactDOM.unmountComponentAtNode(element);
    if(unmountResult && element.parentNode) {
      setTimeout(() => {
        element.parentNode.removeChild(element);
      }, 300);
    }
  }
  // 渲染组件
  const render = ({element, component, config}) => {
    const comInstance = React.createElement(component, {
      ...config,
      key: 'div',
      closeDialog: () => {
        destoryDialog(element)
      },
      visible: true
    })
    ReactDOM.render(comInstance, element)
  }
  return function (config) { // 挂载div
    const element = document.createElement('div');
    render({element, component, config});
    document.getElementsByTagName('body')[0].appendChild(element);
  }
};

export default wrapper;

(2)在warp的基础上包装Modal

import React from 'react';
import {Modal} from 'antd';

import wrapper from './wrapper';

const attrOpts=[
  {
    id:"001",
    value:""
  }
]

const FncModal = (props) => {
  console.log("props:",props)
  const onCancelData = '这是 MemberModal onCancel 传递出来的数据';
  const onOkData = '这是 MemberModal onOK 传递出来的数据';

  const handleCancel = () => {
    props.onCancel(onCancelData);
    props.closeDialog();
  };

  const handleOk = () => {
    props.onOK(onOkData);
    props.closeDialog();
  };

  return(
    <Modal
      title={props.title}
      visible={props.visible}
      onCancel={handleCancel}
      onOk={handleOk}
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </Modal>
  )
};
export default wrapper(FncModal );

(3)外层接受

import React, { useState } from 'react';
import { Table, Button, Divider} from 'antd';
import OpenModal from '../components/openModal';
import FncModal from "../components/FncModal"
const data = [{
  name: '张三',
  age: '12'
}, {
  name: 'tom',
  age: '22'
}]

const Prod = () => {
  const [modalData, setModalData] = useState('111111');

  const columns = [
    {
      dataIndex: 'name',
      title: '姓名'
    },{
      dataIndex: 'age',
      title: '年龄'
    }, {
      title: '操作',
      render: (text, record) => {
        return <div>
          <a onClick={() => showModal('edit',record)}>编辑</a>
          <Divider type="vertical" />
          <a onClick={() => showModal('add',record)}>查看</a>
          <Divider type="vertical" />
          <a >删除</a>
        </div>
      }
    }
  ]

  const handleOk = (okData) => {
    console.log("ok--parent-data:",okData)
    //这里我们接受值
    setModalData(okData);
  };

  const handleCancel = (cancelData) => {
    setModalData(cancelData);
  };


  const showModal = (type,record={}) => {
      console.log("type:",type)
      console.log("record:",record)
      let title = type=== "edit"?"编辑":"新建"
      MemberModal({
        type,
        record,
        onOK: handleOk, //这里是核心
        onCancel: handleCancel, //这里是核心
      })

  };


  return (
    <>
    <hr />
 
      <Table
        dataSource={data}
        columns={columns}
      />
      <p>{modalData}</p>

    </>
  );
};

export default Prod

这样我们就可以通过函数命令式方式来调用Modal。非常方便

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值