1. 程式人生 > >封裝React AntD的dialog彈窗元件

封裝React AntD的dialog彈窗元件

前一段時間分享了基於vue和element所封裝的彈窗元件(封裝Vue Element的dialog彈窗元件),今天就來分享一個基於react和antD所封裝的彈窗元件,反正所使用的技術還是那個技術,情況還是那個情況。只是基於vue所封裝的彈窗元件和基於react所封裝的彈窗元件還是有很大差別的。一樣的是封裝的思想和思路,不一樣的是實現的技術。 至於所用到的技術,還是跟之前分享的有關react元件所用到的技術差不多,無非就是react hooks、函式式元件等。實現思路的話,還是在父元件中開啟彈窗,關閉彈窗的操作就交給所封裝的彈窗元件,不採用那種所謂的給子元件傳一個關閉彈窗的函式,然後讓子元件來觸發,觸發後再由父元件將關閉彈窗的引數傳給子元件。這種實現思路可以是可以,就是太繞了,實現起來也麻煩不是?而且每次使用這個彈窗元件時,還得在每個父元件中都寫一個關閉彈窗的方法,不累嗎?封裝的目的是什麼?一是統一樣式和功能,二是高複用性,三是少寫程式碼,降低開發量,提高開發效率。在我們國家不是有一句很流行的話嗎?“讓專業的人幹專業的事兒”,比如讓姚明出任籃協主席,讓那個所謂“不懂球的胖子”出任乒協主席,就是這個理兒。 當然有人可能會說如果將關閉彈窗的操作只交給彈窗來做的話,那麼萬一要在關閉彈窗後再執行某個操作呢,比如彈窗中嵌套了表單元件,如果有表單正則驗證沒通過,會在表單輸入框下邊有一個紅色的文字提示,此時若關閉彈窗,下次再開啟彈窗時會發現那個紅色的文字提示還在,這個問題咋解決?總不能在關閉彈窗的函式中加入一個重置表單的方法吧,那如果還有其他需求呢,是不是也要在關閉彈窗的函式中再加入一個方法呢?如果其他需求不需要這樣的方法呢?很好,有這樣的疑問,說明你考慮問題很全面,哈哈哈哈哈哈,且這樣的需求也是實實在在存在的,但依然有很好的解決辦法,那就是充分利用彈窗關閉後的回撥方法。 關於彈窗關閉後的回撥方法,antD和element的彈窗元件都有這個方法,只是element的彈窗元件在關閉後有兩個回撥: * close:Dialog關閉的回撥 * closed:Dialog關閉動畫結束時的回撥 對於這兩個回撥,我都拿來試了一把,發現在一般情況下它倆的效果一樣,那麼官方對第二個回撥給的解釋是關閉動畫結束時的回撥,我就有點懵逼了。有興趣的大佬或已經嘗試過的大神別噴我,您就指著我的鼻子,居高臨下地告訴我該怎麼玩這個就可以了,我會虛心接受的。 antD在關閉彈窗後也給了一個回撥afterClose,官方的解釋是Modal完全關閉後的回撥,但人家就只給了這一個關閉後的回撥。好吧,就這個回撥已經足夠我們實現我們的需求了。我們把那些需要在關閉彈窗後再做的一些事情都放在這個回撥中,然後把這個回撥從父元件再傳給所封裝的彈窗子元件就完事了。如果你不傳,代表你沒有這方面的需求,對彈窗的正常工作又沒有絲毫的影響,這豈不是很香嗎? 說了這麼多,光說不練假把式,那就來看具體實現唄。 照例還是先來張效果圖: ![](https://img2020.cnblogs.com/blog/688074/202009/688074-20200910135428736-135269852.png) 1、所封裝的彈窗元件dialog.js ```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 {children}
} 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、使用方法: ```js 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, width: '400px', afterClose: resetForm, // Modal完全關閉後的回撥 } return <>

我是彈窗

我是彈窗

} 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-loade