• react-demo项目:自定义实现一个弹框Dialog组件


    弹框组件的基本项目都会使用到,这次自定义实现一个简单的弹框组件。
    显示标题,内容以及底部
    主要用到的点:https://zh-hans.reactjs.org/docs/portals.html

    Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。

    ReactDOM.createPortal(child, container)
    
    • 1

    第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。第二个参数(container)是一个 DOM 元素。

    代码如下

    src\components\Dialog\index.jsx文件

    
    import React, { forwardRef, useEffect, useMemo, useState } from 'react'
    import ReactDOM from 'react-dom';
    import style from './index.css';
    
    function Dialog(props) {
      const { visible = false, title, children, footer } = props;
    
      useEffect(() => {
        // 查找dialog节点
        let dom = document.getElementById('dialog');
    
        // 存在即删除
        (!visible && dom) && document.body.removeChild(dom);
    
        // 设置属性id
        let divDialog = document.createElement('div');
        divDialog.setAttribute('id', 'dialog');
        divDialog.setAttribute('class', 'dialog');
        document.body.append(divDialog)
    
      }, [])
    
      return (
        <>
          {
            (document.getElementById('dialog') && visible) && ReactDOM.createPortal(
              <div className={style['H-Dialog-overview']}>
                <div className={style['H-Dialog-inner']}>
                  <div className={style['dialog-header']}>
                    <h3>{title}</h3>
    
                  </div>
                  <div className={style['dialog-body']}>
                    {children}
                  </div>
                  <div className={style['dialog-footer']}>
                    {footer}
                  </div>
    
                </div>
              </div>, document.getElementById('dialog'))
          }
        </>
      )
    
    }
    
    export default Dialog
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    src\components\Dialog\index.css文件

    .dialog {
    
    }
    .H-Dialog-overview {
      /* 设置弹框背景以及无法点击页面*/
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1001;
      background-color: rgba(0, 0,0,0.6);
      display: flex;
      justify-content: center;
      
    }
    .H-Dialog-inner {
      height: 200px;
      width: 400px;
      background-color: #fff;
      position: absolute;
      top: 20vh;
      padding: 20px;
    }
    .dialog-header {
      margin-bottom: 10px;
    }
    .dialog-body{
    
    }
    .dialog-footer {
      position: absolute;
      bottom: 20px;
      margin: auto;
      text-align: center;
      
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    组件使用

    src\pages\Home\index.jsx文件

    import { Button } from 'antd';
    import React, { useState } from 'react';
    import Dialog from '../../components/Dialog/index.jsx'
    
    export default function Home() {
    
      const [visible, setVisible] = useState(false)
      return (
        <div className="H-Home">
          <h2>home</h2>
          <h4>ui</h4>
          <div>
            <Button type='primary' onClick={() => {
              setVisible(true)
            }}>计算</Button>
          </div>
    
          <Dialog
            visible={visible}
            title={"这是一个弹窗"}
            footer={
              <>
                <Button onClick={() => {
                  setVisible(false)
                }}>确定</Button>
              </>
            }
          >
            <div>
              hello
            </div>
          </Dialog>
        </div>
      )
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    效果图

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Spring版本特性--->Spring各个版本引入了哪些新特性?-1
    Windows环境安装dmPython(WHL方式)
    AI调度程序突然很多推送AI任务失败----是redis的锅吗
    AWS 中文入门开发教学 39- AWS CLI - AWS认证 必须会的命令行工具
    计算机毕业设计 基于SSM的支教志愿者招聘系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    工作即将灭绝?AI大模型的入侵比你想象得还要快!
    亲测可用:Axios携带自定义的Cookie解决方案
    这些比较前沿的设计网站,你知道吗?
    Linux内核面试题(3)
    [libevent:构建高性能事件驱动应用的利器]
  • 原文地址:https://blog.csdn.net/weixin_40119412/article/details/128200572