广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >react实现Modal弹窗效果
  • 151
分享到

react实现Modal弹窗效果

2024-04-02 19:04:59 151人浏览 安东尼
摘要

本文实例为大家分享了React实现Modal弹窗效果的具体代码,供大家参考,具体内容如下 一、Dialog.js文件 import React, {useMemo, useEffec

本文实例为大家分享了React实现Modal弹窗效果的具体代码,供大家参考,具体内容如下

一、Dialog.js文件

import React, {useMemo, useEffect, useState} from 'react'
import ReactDOM from 'react-dom'





// 控制弹窗隐藏以及动画效果
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
        //    触发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>
    }
}


// 静态方法
let ModalContainer = null
const modelSymbol = Symbol('$$_model_Container_hidden')

// 静态属性show——控制
Modal.show = (config) => {
    //  如果modal已经存在,name就不需要第二次show
    if (ModalContainer) return
    const props = {...config, visible: true}
    const container = ModalContainer = document.createElement('div')
    // 创建一个管理者,管理model状态
    const manager = container[modelSymbol] = {
        setShow: null,
        mounted: false,
        hidden() {
            const {setShow} = manager
            setShow && setShow(false)
        },
        destroy() {
            //    卸载组件
            ReactDOM.unmountComponentAtnode(container)
            // 移除节点
            document.body.removeChild(container)
            // 置空元素
            ModalContainer = null
        }
    }

    const ModelApp = (props) => {
        const [show, setShow] = useState(false)
        manager.setShow = setShow
        const {visible, ...trueProps} = props
        useEffect(() => {
            // 加载完成,设置状态
            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'


export default function App() {
    const [ visible , setVisible ] = useState(false)
    const [ nameShow , setNameShow ] = useState(false)
    const handleClick = () => {
        setVisible(!visible)
        setNameShow(!nameShow)
    }
    
    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>
}

实现效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: react实现Modal弹窗效果

本文链接: https://www.lsjlt.com/news/166027.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • react实现Modal弹窗效果
    本文实例为大家分享了react实现Modal弹窗效果的具体代码,供大家参考,具体内容如下 一、Dialog.js文件 import React, {useMemo, useEffec...
    99+
    2022-11-13
  • Vue如何实现弹窗Modal
    这篇文章给大家分享的是有关Vue如何实现弹窗Modal的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Vue作为最近最炙手可热的前端框架,其简单的入门方式和功能强大的API是其优点...
    99+
    2022-10-19
  • React实现动效弹窗组件
    我们在写一些 UI 组件时,若不考虑动效,就很容易实现,主要就是有无的切换(类似于 Vue 中的 v-if 属性)或者可见性的切换(类似于 Vue 中的 v-show 属性)。 1...
    99+
    2022-11-12
  • bootstrap modal+gridview如何实现弹出框效果
    小编给大家分享一下bootstrap modal+gridview如何实现弹出框效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧...
    99+
    2022-10-19
  • Android实现Window弹窗效果
    本文实例为大家分享了Android实现Window弹窗效果的具体代码,供大家参考,具体内容如下 效果图 第一步 准备弹窗的布局,新建XML文件 photo_window &l...
    99+
    2022-11-12
  • vue实现弹窗拖拽效果
    本文实例为大家分享了vue实现弹窗拖拽效果的具体代码,供大家参考,具体内容如下 前言 实现拖拽其实简单来说就分为三步 一、创建一个js文件 因为本身dialog窗口不具备移动拖拽能力...
    99+
    2022-11-13
  • Flutter实现底部弹窗效果
    目录实现效果代码结构基本使用自定义底部弹窗总结在实际开发过程中,经常会用到底部弹窗来进行快捷操作,例如选择一个选项,选择下一步操作等等。在 Flutter 中提供了一个 showMo...
    99+
    2022-11-12
  • Vue实现简单弹窗效果
    本文实例为大家分享了Vue实现简单弹窗效果的具体代码,供大家参考,具体内容如下 选中input 弹出选项框 显示弹窗 首先要在components中新建两个组件 要实现子组件向父...
    99+
    2022-11-13
  • Android实现底部弹窗效果
    本文实例为大家分享了Android实现底部弹窗效果的具体代码,供大家参考,具体内容如下源代码地址:https://github.com/luoye123/Box东西很简单,我就直接亮代码了: activity_main.xml<...
    99+
    2023-05-31
    android 弹窗 roi
  • jquery实现简单的弹窗效果
    本文实例为大家分享了jquery实现简单弹窗效果的具体代码,供大家参考,具体内容如下 效果实现图 css代码 h1,p,h2{ margin: 0; padding: ...
    99+
    2022-11-12
  • vue自定义实例化modal弹窗功能的实现
    目录需求背景下面进行相关讲解需求背景 使用iview时发现其定义的this.$Modal.confirm()不能进行样式修改,并且秉承着对新知识的追求,故此有了以下的开发 按照我的文...
    99+
    2022-11-13
  • Android实现底部支付弹窗效果
    Android底部支付弹窗实现的效果: 实现的思路: 1.通过继承PopupWindow自定义View来达到弹窗的弹出效果; 2.通过回调将输入的密码由弹窗传入到主界面中; ...
    99+
    2022-06-06
    弹窗 Android
  • jQuery如何实现弹窗遮罩效果
    这篇文章给大家分享的是有关jQuery如何实现弹窗遮罩效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。效果图:图(1)初始图图(2)点击按钮后代码如下:<!DOCTYPE...
    99+
    2022-10-19
  • js如何实现弹窗暗层效果
    这篇文章给大家分享的是有关js如何实现弹窗暗层效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。示例代码:<!DOCTYPE html> <html&...
    99+
    2022-10-19
  • vue实现弹窗翻页多选效果
    本文实例为大家分享了vue实现弹窗翻页多选效果的具体代码,供大家参考,具体内容如下 最终效果 点选择按钮后,弹出选择用户弹窗,可翻页勾多个用户  完整代码 <te...
    99+
    2022-11-13
  • Android开发之PopupWindow实现弹窗效果
    本文实例为大家分享了Android开发之PopupWindow实现弹窗的具体代码,供大家参考,具体内容如下 基本框架 在activity_main.xml中设置一个按钮,用于唤出弹窗...
    99+
    2022-11-13
  • React实现pc端的弹出框效果
    本文实例为大家分享了React实现pc端弹出框效果的具体代码,供大家参考,具体内容如下 最近学习react碰见了一个小坑 不知道为什么 我在做一个弹出框的小demo 很简单的一个小...
    99+
    2022-11-13
  • 实现jQuery弹窗效果的示例分析
    这篇文章主要介绍实现jQuery弹窗效果的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!本文实例为大家分享了jQuery弹窗效果展示的具体代码,供大家参考,具体内容如下<...
    99+
    2022-10-19
  • vue 实现弹窗关闭后刷新效果
    目录vue弹窗关闭后刷新效果问题解决关闭或刷新vue文件弹出提示框vue弹窗关闭后刷新效果 问题 列表点击进入详情时弹窗内容重新赋值,但是修改后未点击保存再打开同一个弹窗,数据是关闭...
    99+
    2022-11-13
  • Android开发实现多进程弹窗效果
    安卓开发之多进程弹窗,供大家参考,具体内容如下 背景 有时在弹窗绘图时,需要弹窗在新的进程中,以保证在弹窗绘图的过程中不会占用过多的内存导致主进程被关。 代码实现 子进程弹窗 首先我...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作