gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

react怎么實現(xiàn)彈出模態(tài)框

react實現(xiàn)彈出模態(tài)框的方法:1、用createPortal把元素直接渲染到“document.body”下;2、通過“modelShow”和“modelShowAync”來控制彈窗的顯示隱藏;3、用一個控制器controlShow來流暢執(zhí)行更新任務即可。

react怎么實現(xiàn)彈出模態(tài)框

本教程操作環(huán)境:Windows10系統(tǒng)、react18.0.0版、Dell G3電腦。

react怎么實現(xiàn)彈出模態(tài)框?

react實現(xiàn)Modal彈窗

一、Dialog.js文件

import React, {useMemo, useEffect, useState} from 'react' import ReactDOM from 'react-dom' /**  *  * 需要把元素渲染到組件之外,用 createPortal 把元素直接渲染到 document.body 下,為了防止函數(shù)組件每一次執(zhí)行都觸發(fā) createPortal, 所以通過 useMemo 做性能優(yōu)化。  因為需要漸變的動畫效果,所以需要兩個變量 modelShow / modelShowAync 來控制顯示/隱藏,modelShow 讓元素顯示/隱藏,modelShowAync 控制動畫執(zhí)行。  當彈窗要顯示的時候,要先設置 modelShow 讓組件顯示,然后用 setTimeout 調度讓 modelShowAync 觸發(fā)執(zhí)行動畫。  當彈窗要隱藏的時候,需要先讓動畫執(zhí)行,所以先控制 modelShowAync ,然后通過控制 modelShow 元素隱藏,和上述流程相反。  用一個控制器 controlShow 來流暢執(zhí)行更新任務。  */ // 控制彈窗隱藏以及動畫效果 const controlShow = (f1, f2, value, timer) => {     f1(value)     return setTimeout(() => {         f2(value)     }, timer) } export const Dialog = (props) => {     const {width, visible, closeCb, onClose} = props     // 控制 modelShow動畫效果     const [modelShow, setModelShow] = useState(visible)     const [modelShowAsync, setModelShowAsync] = useState(visible)     const renderChildren = useMemo(() => {         // 把元素渲染到組件之外的document.body 上         return ReactDOM.createPortal(<div style={{display: modelShow ? 'block' : 'none'}}>             <div className="model_container" style={{opacity: modelShowAsync ? 1 : 0}}>                 <div className="model_wrap">                     <div style={{width: width + 'px'}}> {props.children} </div>                 </div>             </div>             <div className="model_container mast" onClick={() => onClose && onClose()}                  style={{opacity: modelShowAsync ? 0.6 : 0}}/>         </div>, document.body)     }, [modelShow, modelShowAsync])     useEffect(() => {         let timer         if (visible) {             // 打開彈窗,             timer = controlShow(setModelShow, setModelShowAsync, visible, 30)         } else {             timer = controlShow(setModelShowAsync,setModelShow,visible,1000)         }         return () => {             timer && clearTimeout(timer)         }     }, [visible])     return renderChildren }
登錄后復制

二、Modal.js

import {Dialog} from "./Dialog"; import React, {useEffect, useState} from 'react' import ReactDOM from 'react-dom' import './style.scss' class Modal extends React.PureComponent {     // 渲染底部按鈕     renderFooter = () => {         const {onOk, onCancel, cancelText, okText, footer} = this.props         //    觸發(fā)onOk / onCancel回調         if (footer && React.isValidElement(footer)) return footer         return <div className="model_bottom">             <div className="model_btn_box">                 <button className="searchbtn"                         onClick={(e) => {                             onOk && onOk(e)                         }}>{okText || '確定'}                 </button>                 <button className="concellbtn"                         onClick={(e) => {                             onCancel && onCancel(e)                         }}>{cancelText || '取消'}                 </button>             </div>         </div>     }     // 渲染底部     renderTop = () => {         const {title, onClose} = this.props         return <div className="model_top">             <p>{title}</p>             <span className="model_top_close" onClick={() => onClose && onClose()}>X</span>         </div>     }     // 渲染彈窗內容     renderContent = () => {         const {content, children} = this.props         return React.isValidElement(content) ? content : children ? children : null     }     render() {         const {visible, width = 500, closeCb, onClose} = this.props         return <Dialog             closeCb={closeCb}             onClose={onClose}             visible={visible}             width={width}         >             {this.renderTop()}             {this.renderContent()}             {this.renderFooter()}         </Dialog>     } } // 靜態(tài)方法 let ModalContainer = null const modelSymbol = Symbol('$$_model_Container_hidden') // 靜態(tài)屬性show——控制 Modal.show = (config) => {     //  如果modal已經存在,name就不需要第二次show     if (ModalContainer) return     const props = {...config, visible: true}     const container = ModalContainer = document.createElement('div')     // 創(chuàng)建一個管理者,管理model狀態(tài)     const manager = container[modelSymbol] = {         setShow: null,         mounted: false,         hidden() {             const {setShow} = manager             setShow && setShow(false)         },         destroy() {             //    卸載組件             ReactDOM.unmountComponentAtNode(container)             // 移除節(jié)點             document.body.removeChild(container)             // 置空元素             ModalContainer = null         }     }     const ModelApp = (props) => {         const [show, setShow] = useState(false)         manager.setShow = setShow         const {visible, ...trueProps} = props         useEffect(() => {             // 加載完成,設置狀態(tài)             manager.mounted = true             setShow(visible)         }, [])         return <Modal {...trueProps} closeCb={() => manager.mounted && manager.destroy()} visible={show}/>     }     // 插入到body中     document.appendChild(container)     // 渲染React元素     ReactDOM.render(<ModelApp/>, container)     return manager } Modal.hidden = () => {     if(!ModalContainer) return     // 如果存在ModalContainer 那么隱藏ModalContainer     ModalContainer[modelSymbol] && ModalContainer[modelSymbol].hidden() } export default Modal
登錄后復制

三、style.scss樣式文件

$bg-linear-gradien-red-light : linear-gradient(135deg, #fc4838 0%, #f6346b  100%); $bg-linear-gradien-red-dark : linear-gradient(135deg, #fc4838 0%, #f6346b  100%); .constrol{   padding: 30px;   width: 500px;   border: 1px solid #ccc;   height: 200px; } .feel{   padding: 24px; } .model_top{   height: 40px;   border-radius: 5px  5px 0 0 ;   position: relative;   p{     height: 40px;     font-weight: bold;     line-height: 40px;     padding-left: 14px;   }   background-color: #eee;   .model_top_close{     position: absolute;     font-size: 16px;     cursor: pointer;     right: 24px;     top: 8px;   } } .model_bottom{   height: 50px;   padding-top: 10px;   .model_btn_box{     display: inline-block;     margin-left: 50%;     transform: translateX(-50%);   } } .model_container{   .model_wrap{     position: absolute;     border-radius:5px ;     background: #fff;     left:50%;     top:50%;     transform: translate(-50%,-50%);   }   position: fixed;   z-index: 10000;   left:0;   top:0;   transition: opacity 0.3s;   right: 0;   bottom: 0; } .mast{   background-color: #000;   z-index: 9999; } .searchbtn{   background: linear-gradient(135deg, #fc4838 0%, #f6346b  100%);   color: #fff;   min-width: 96px;   height :36px;   border :none;   border-radius: 18px;   font-size: 14px;   font-weight: 500;   cursor: pointer;   margin-left: 20px !important; } .searchbtn:focus{   background: $bg-linear-gradien-red-dark;   color: #fff;   min-width: 96px;   height: 36px;   border: none;   border-radius: 18px;   font-size: 14px;   font-weight: 500;   cursor: pointer;   margin-left: 20px !important;   box-shadow: 0 2px 7px 0 #FAA79B; } .searchbtn:hover{   background :$bg-linear-gradien-red-light;   color :#fff;   min-width: 96px;   height :36px;   margin-left: 20px !important;   border: none;   border-radius: 18px;   font-size :14px;   font-weight: 500;   cursor: pointer;   box-shadow: 0 2px 7px 0 #FAA79B; } .searchbtn:disabled{   background: #c0c6c6;   color :#fff;   min-width: 96px;   height :36px;   font-size :14px;   font-weight: 500;   border: none;   border-radius: 18px;   cursor: not-allowed; } .concellbtn{   background :#fff;   color :#303133;   width: 96px;   height: 36px;   font-size: 14px;   font-weight: 500;   border :1px solid #E4E7ED;   border-radius: 18px;   cursor: pointer;   // margin-right: 10px;   margin-left: 10px; } .concellbtn:hover{   background :rgba(220, 223, 230, 0.1);   color: #303133;   width :96px;   height: 36px;   font-size: 14px;   font-weight: 500;   border :1px solid #E4E7ED;   border-radius: 18px;   cursor: pointer;   // margin-right: 10px;   margin-left: 10px; } .concellbtn:focus{   background :rgba(220, 223, 230, 0.24);   color: #303133;   width :96px;   height: 36px;   font-size: 14px;   font-weight: 500;   border: 1px solid #C0C4CC;   border-radius: 18px;   cursor: pointer;   margin-right: 10px;   margin-left: 10px; }
登錄后復制

四、調用例子

import React, {useState, useMemo} from 'react' import Modal from './customPopup/Modal' /* 掛載方式調用modal */ export default function App() {     const [ visible , setVisible ] = useState(false)     const [ nameShow , setNameShow ] = useState(false)     const handleClick = () => {         setVisible(!visible)         setNameShow(!nameShow)     }     /* 防止 Model 的 PureComponent 失去作用 */     const [ handleClose ,handleOk, handleCancel ] = useMemo(()=>{         const Ok = () =>  console.log('點擊確定按鈕')         const Close = () => setVisible(false)         const Cancel = () => console.log('點擊取消按鈕')         return [Close , Ok , Cancel]     },[])     return <div>         <Modal             onCancel={handleCancel}             onClose={handleClose}             onOk={handleOk}             title={'標題'}             visible={visible}             width={700}         >             <div className="feel" >               內容。。。。。。。             </div>         </Modal>         <button onClick={() => {             setVisible(!visible)             setNameShow(false)         }}         > model show </button>         <button onClick={handleClick} > model show ( 顯示作者 ) </button>     </div> }
登錄后復制

實現(xiàn)效果

react怎么實現(xiàn)彈出模態(tài)框

推薦學習:《react視頻教程》

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
一本久道中文无码字幕av| 欧美深夜福利视频| 我的公把我弄高潮了视频| www.亚洲高清| 99视频在线免费| 亚洲人成无码网站久久99热国产 | 8x8x最新地址| www午夜视频| 久热精品在线播放| 国产福利在线免费| 亚洲色图偷拍视频| 日本在线视频www色| 黄色一级片av| www.激情网| 成人一区二区三| 人人爽人人av| 拔插拔插海外华人免费| www.在线观看av| www.xxx亚洲| 国产小视频精品| 中文字幕视频三区| 欧洲精品视频在线| 久草热视频在线观看| www.超碰com| 国内av一区二区| 少妇av一区二区三区无码| 国产二区视频在线播放| 日韩不卡一二三| theporn国产精品| 成人在线播放网址| 成人在线观看黄| 青青草综合视频| 97成人在线免费视频| 日韩一级理论片| japanese在线视频| www.日日操| 欧洲xxxxx| 999久久久精品视频| 精品国产一区二区三区无码| 久久免费视频3| 久久精品一二三四| 91热这里只有精品| 国产又爽又黄ai换脸| 少妇无码av无码专区在线观看| 苍井空浴缸大战猛男120分钟| 99精品视频免费版的特色功能| 免费一级特黄毛片| 国产永久免费网站| 欧美日韩在线一| 做爰高潮hd色即是空| 97xxxxx| 免费不卡av在线| 小说区视频区图片区| 无码精品国产一区二区三区免费| 午夜啪啪免费视频| 91人人澡人人爽人人精品| 日本免费a视频| 潘金莲一级淫片aaaaa免费看| 日本三级免费观看| 18禁网站免费无遮挡无码中文| 性欧美1819| 日韩av在线中文| 91人人澡人人爽人人精品| 国产特级淫片高清视频| 国产亚洲精品久久久久久久| 天堂一区在线观看| 999精品视频在线| 国产裸体舞一区二区三区| 国产午夜福利在线播放| 真人抽搐一进一出视频| 国产一级不卡视频| 99色精品视频| 欧美爱爱视频免费看| 丝袜人妻一区二区三区| 国产精品久久久久7777| 国产欧美日韩网站| 男人揉女人奶房视频60分| 秋霞无码一区二区| 国产免费黄视频| 熟女人妇 成熟妇女系列视频| 免费无码不卡视频在线观看| 每日在线观看av| 春日野结衣av| 狠狠热免费视频| 天天影视色综合| 欧美 国产 精品| 人妻夜夜添夜夜无码av | 日本福利视频网站| 日韩五码在线观看| 成年人免费在线播放| 色综合av综合无码综合网站| 国产精品入口免费软件| 三级性生活视频| 久久国产午夜精品理论片最新版本| 日韩精品一区二区在线视频| 无码播放一区二区三区| 天天影视综合色| 男插女免费视频| 日韩精品 欧美| 日本一二区免费| a级黄色小视频| 国产九九在线视频| 青青草免费在线视频观看| 欧美老熟妇喷水| 一级黄色高清视频| 女人天堂av手机在线| 国产探花在线看| 国产二级片在线观看| 中文字幕网av| 国产婷婷一区二区三区| 国内自拍第二页| 免费在线观看日韩视频| 97超碰人人爱| 五月天婷婷亚洲| 一女被多男玩喷潮视频| 91精品国产吴梦梦| 日韩av在线中文| 欧美日韩一区二区在线免费观看| 可以免费看的黄色网址| 欧美国产日韩在线播放| www.日本在线播放| 日韩一二区视频| 日韩精品在线播放视频| 噼里啪啦国语在线观看免费版高清版 | 日韩欧美精品在线观看视频| 欧美日韩亚洲国产成人| 欧美在线观看视频网站| 成人黄色大片网站| 一本大道东京热无码aⅴ| 亚洲精品视频三区| 中文字幕视频在线免费观看| 波多野结衣50连登视频| 黄页网站在线观看视频| 996这里只有精品| 欧美 国产 精品| 玖玖精品在线视频| 亚洲免费视频播放| 欧洲美女和动交zoz0z| 图片区乱熟图片区亚洲| 国产永久免费网站| 日本女人高潮视频| 7777在线视频| youjizz.com在线观看| 国产精品视频一二三四区| 国产 国语对白 露脸| 六月婷婷激情网| 免费的一级黄色片| 欧美人成在线观看| 男人日女人逼逼| 成年人在线看片| 国产精品v日韩精品v在线观看| 91国产精品视频在线观看| 538在线视频观看| 一区二区久久精品| 国产香蕉一区二区三区| 久久久久久www| 少妇人妻互换不带套| 在线观看免费视频高清游戏推荐| 中文字幕剧情在线观看| 日韩欧美一级在线| 青青青免费在线| 中文字幕国内自拍| 成人手机在线播放| 中文字幕日本最新乱码视频| 污污网站免费观看| 免费一级淫片aaa片毛片a级| 国产又黄又大又粗视频| 向日葵污视频在线观看| 可以在线看黄的网站| 国模杨依粉嫩蝴蝶150p| 中文字幕剧情在线观看| 欧美一区二区中文字幕| 日韩av卡一卡二| 97成人在线免费视频| 手机成人av在线| 日韩在线xxx| 野外做受又硬又粗又大视频√| 任你操这里只有精品| 99热都是精品| 欧美一级特黄a| 欧美日本视频在线观看| 一级做a爱视频| 欧美韩国日本在线| 日韩a级黄色片| 天堂视频免费看| 99热成人精品热久久66| 日韩精品视频在线观看视频| 在线观看免费视频高清游戏推荐| 精品人妻少妇一区二区| 99中文字幕在线观看| 久久久久久久久久一区| 免费无码av片在线观看| 99国产精品白浆在线观看免费| 中文字幕第17页| 男女视频在线看| 日本熟妇人妻xxxxx| 久久国产成人精品国产成人亚洲| 国产精品av免费观看| 国产高潮呻吟久久久| 欧美激情第四页|