react实现全局组件确认弹窗

本例基于react实现了一个简单的确认弹窗,可以让我们在项目中根据需要随时调用

创建全局modal组件

此处我将弹窗模态框独立出来,用户可以通过传入组件或Element来填充模态框的内容。

import ReactDOM from 'react-dom';
import React, { Fragment } from 'react';
import Button from 'components/common/button';
import Icon from 'components/common/icon';
import css from './index.less';

export interface Props {
  isCancelIcon?: boolean;
  cancelText?: string;
  okText?: string;
  onCancel?: () => void;
  onOk?: () => void;
  footer?: React.ReactNode;
  style?: object;
}

const Modal: React.FC<Props> = React.memo<Props>(({
  isCancelIcon, cancelText, okText, onOk, onCancel, footer, children, style
}) => {

  function renderBtn() {
    return (
      <Fragment>
        <Button 
          className={css.btn}
          onClick={() => onCancel()}
        >
          {cancelText}
        </Button>
        <Button 
          className={css.btn} 
          onClick={() => onOk()} 
          type="primary">
          {okText}
        </Button>
      </Fragment>
    );
  }

  return (
    <div className={css.masker}>
      <div className={css.box} style={{ ...style }} >
        {isCancelIcon && 
        <div 
          className={css.cancelIconBox}
          onClick={() => onCancel()}
        >
          <Icon className={css.cancelIcon} />
        </div>}
        {children}
        <div className={css.btnBox}>
          {footer || renderBtn()}
        </div>
      </div>
    </div>
  );
});

Modal.defaultProps = {
  okText: '确定',
  cancelText: '取消',
  onCancel: () => {},
  onOk: () => {},
  isCancelIcon: true
};

export default function ({ content, props }: { content: React.ReactNode; props: Props }) {
  
  const { onOk=() => {}, onCancel=() => {}, ...others } = props;
  /**
   * 取消操作,关闭弹窗
   */
  function handleClose() {
    ReactDOM.unmountComponentAtNode(div);
    document.body.removeChild(div);
    onCancel();
  }
  /**
   * 确认操作,关闭弹窗
   */
  function handleOk() {
    ReactDOM.unmountComponentAtNode(div);
    document.body.removeChild(div);
    onOk();
  }

  let div = document.createElement('div');
  document.body.appendChild(div);
  ReactDOM.render(
    <Modal 
      {...others}
      onOk={handleOk} 
      onCancel={handleClose}
    >
      {content}
    </Modal>,
    div);

  return {
    handleOk: () => handleOk(),
    handleClose: () => handleClose()
  };
}

less文件

@import '~common/less/index.less';
  .masker{
    width: 100vw;
    height: 100vh;
    background: @mask-color;
    position: fixed;
    left: 0;
    top: 0;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
    .box{
      width: 500px;
      height: 230px;
      position: relative;
      background-color: white;
      position: relative;
      transition: .2s;
      animation: showModal .2s ease-in forwards;
      .cancelIconBox{
        width: 27px;
        height: 27px;
        line-height: 27px;
        text-align: center;
        position: absolute;
        right: 15px;
        top: 22px;
        cursor: pointer;
        .cancelIcon{
          .font(17px)
        }
      }
      .btnBox{
        width: 100%;
        position: absolute;
        left: 0;
        bottom: 20px;
        padding-right: 10px;
        display: flex;
        flex-flow: row;
        justify-content: flex-end;
        align-items: center;
          .btn{
            margin-right: 10px;
            .font(12px)
          }
        }
    }
  }

  @keyframes showModal {
    0%{
      transform:translate(-100px, 60px) scale(.5) ;
    }
    100%{
      transform:translate(0, 0) scale(1)  ;
    }
  }

确认框内容组件

此组件用以渲染确认框具体内容,项目中可根据具体情况渲染自己需要的内容

tsx文件

import React from 'react';
import classNames from 'classnames';
import Icon from 'components/common/icon';
import modal, { Props as ModalProps } from '../components/modal';
import css from './index.less';

interface Content {
  key: string;
  value: string;
}

export interface Props extends ModalProps {
  title?: string;
  content?: Content[];
}

export default function success({ title, content, ...others }: Props) {

  const node = (
    <div className={css.successWrap}>
      <div className={css.line} />
      <div className={css.content}>
        <Icon className={css.successIcon} />
        <div className={css.right}>
          <span className={css.successTitle}>{title}</span>
          {
            content && content.map((item, index) => {
              return (
                <div key={`content_${index}`} className={css.contentList}>
                  <div className={css.key}>{item.key}:</div>
                  <span>{item.value}</span>
                </div>
              );
            })
          }
        </div>
      </div>
    </div>
  );

  modal({
    content: node,
    props: others
  });
}

less文件

@import '~common/less/index.less';
  .successWrap{
    .line{
      width: 100%;
      height: 8px;
      background-color: #6EA204;
    }
    .content{
      display: flex;
      flex-flow: row;
      margin: 30px 0 0 40px;
      .successIcon{
        .font(72px);
      }
      .right{
        display: flex;
        flex-flow: column;
        padding-top: 10px;
        margin-left: 20px;
        .successTitle{
          .contentList();
          .font(18px);
          font-weight:500;
        }
        .contentList{
          display: flex;
          flex-flow: row;
          .font(12px);
          font-weight:400;
          color:@font-title-color;
          margin-bottom: 7px;
          .key{
            min-width: 72px;
          }
        }
      }
    }
  }

使用全局确认框

只需要在组件中引入全局组件,然后直接调用全局组件中的方法即可。

import React from 'react';
import success from 'components/common/confirm/success';
const content = [
  { 
    key: '代理商姓名',
    value: '东东东'
  },
  { 
    key: '联系方式',
    value: '18978765678'
  },
  { 
    key: '代理商账号',
    value: '这是一个测试登录用户名'
  },
  { 
    key: '初始密码',
    value: '这是一个测试登录用户名'
  },
];
export interface Props {}
const Components: React.FC<Props> = () => {

return (
 <Button onClick={() => success({ 
 content, title: '代理商录入成功', 
 okText: '继续录入', 
 cancelText: '返回列表' 
 })}
 >成功状态框</Button>
)

Components.defaultProps = {};

export default Components

实现效果

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

(0)

相关推荐

  • React实现动效弹窗组件

    我们在写一些 UI 组件时,若不考虑动效,就很容易实现,主要就是有无的切换(类似于 Vue 中的 v-if 属性)或者可见性的切换(类似于 Vue 中的 v-show 属性). 1. 没有动效的弹窗 在 React 中,可以这样来实现: interface ModalProps { open: boolean; onClose?: () => void; children?: any; } const Modal = ({open. onClose, children}: ModalProps)

  • react-native弹窗封装的方法

    本文实例为大家分享了react-native弹窗封装的具体代码,供大家参考,具体内容如下 上图 仿苹果弹窗组件(android+ios均可用) 以上效果均基于本文的弹窗组件,后续将会介绍上面的组件,也可基于改组件定制更多组件 安装依赖 yarn add react-native-root-siblings 或者 npm install react-native-root-siblings --save 主要代码 显示弹窗 export const showModal = (component)

  • React弹窗使用方式NiceModal重新思考

    目录 一些有趣的真实场景 案例一:全局弹窗 案例二:存在分支以及依赖关系的弹窗 不那么通用的解决方案 可能是最好的弹窗实践 创建弹窗 使用弹窗 简单实现思路 推荐阅读 一些有趣的真实场景 在开始进入正题之前,先看看一些与弹窗有关的有趣场景

  • react实现全局组件确认弹窗

    本例基于react实现了一个简单的确认弹窗,可以让我们在项目中根据需要随时调用 创建全局modal组件 此处我将弹窗模态框独立出来,用户可以通过传入组件或Element来填充模态框的内容. import ReactDOM from 'react-dom'; import React, { Fragment } from 'react'; import Button from 'components/common/button'; import Icon from 'components/comm

  • React实现全局组件的Toast轻提示效果

    Toast是常用的轻提示弹框,常用于页面loading和提示语弹窗. 本例基于React实现一个随时可调用且不随页面渲染的全局组件. 需求分析 Toast 不需要同页面一起被渲染,而是根据需要被随时调用. Toast 是一个轻量级的提示组件,它的提示不会打断用户操作,并且会在提示的一段时间后自动关闭. Toast 需要提供几种不同的消息类型以适应不同的使用场景. Toast 的方法必须足够简洁,以避免不必要的代码冗余. 如何使用 首先引入 import Toast from './compone

  • 进入Hooks时代写出高质量react及vue组件详解

    目录 概述 1.组件什么时候拆?怎么拆? 2.如何组织拆分出的组件文件? 3.如何用hooks抽离组件逻辑? 题外话:全局状态的管理 概述 vue和react都已经全面进入了hooks时代(在vue中也称为组合式api,为了方便后面统一称为hooks),然而受到以前react中类组件和vue2写法的影响,很多开发者都不能及时转换过来,以致于开发出一堆面条式代码,整体的代码质量反而不如改版以前了. hooks组件到底应该如何写,我也曾为此迷惘过一段时间.特别我以前以react开发居多,但在转到新岗

  • 最简单的vue消息提示全局组件的方法

    简介 实现功能 自定义文本 自定义类型(默认,消息,成功,警告,危险) 自定义过渡时间 使用vue-cli3.0生成项目 toast全局组件编写 /src/toast/toast.vue <template> <div class="app-toast" v-if="isShow" :class="{'info': type=== 'info','success': type=== 'success','wraning': type===

  • React 高阶组件HOC用法归纳

    一句话介绍HOC 何为高阶组件(HOC),根据官方文档的解释:"高阶组件是react中复用组件逻辑的一项高级技术.它不属于react API的组成部分,它是从react自身组合性质中抽离出来的一种模式.具体来说,高阶组件是函数,它接受一个组件作为参数,然后返回一个新的组件 使用场景 将几个功能相似的组件里面的方法和react特性(如生命周期里面的副作用)提取到HOC中,然后向HOC传入需要封装的组件.最后将公用的方法传给组件. 优势 使代码简洁优雅.代码量更少 HOC(高阶组件) /* HOC(

  • react四种组件中DOM样式设置方式详解

    1.行内样式 想给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现 行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方 例如:render函数里.组件原型上.外链js文件中 注意:这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号 <p style={{color:'red', fontSize:'14px'}}>Hello world</p> 2.使用class React推荐我们使用行内样式,因为React觉得每一个组件都是一

  • react封装全局弹框的方法

    本文实例为大家分享了react封装全局弹框的具体代码,供大家参考,具体内容如下 弹框效果图 文件布局 index.js /* eslint-disable react/no-render-return-value */ import React, { Component } from 'react' import { is, fromJS } from 'immutable' import ReactDOM from 'react-dom' import './alert.less' const

  • React创建对话框组件的方法实例

    原生的前端体系创建一个对话框可是再简单不过了.但是如果放到组件化思想下的react体系中,想要制作一个属于自己的对话框还是有一定的麻烦的.主要遇到的问题有两个:一是如何在子组件中创建body下的对话框组件,二是如何删除这个组件. 接下来我们就一步一步解决这两个问题. 我们先写好dialog组件:(所有的样式都不写了,这里实现一个原型) class Dialog extends Component{ constructor(props){ super(props); } render(){ ret

  • React封装CustomSelect组件思路详解

    目录 思路和前提 编码与实现 处理createContext与useContext 对content的封装和拆分: DispatchRender, Controls 先说Controls, 包含控制行: 重置, 确定 DispatchRender 用于根据type分发对应的render子组件,这是一种编程思想,在次可以保证父子很大程度的解耦,再往下子组件不再考虑type是什么,父组件不需要考虑子组件有什么. 单选框的render子组件的具体实现 由来: 需要封装一个通过Popover弹出框里可以

  • React Native 中实现确认码组件示例详解

    目录 正文 实现原理 开源方案 正文 确认码控件也是一个较为常见的组件了,乍一看,貌似较难实现,但实则主要是障眼法. 实现原理 上图 CodeInput 组件的 UI 结构如下: <View style={[styles.container]}> <TextInput autoFocus={true} /> <View style={[styles.cover, StyleSheet.absoluteFillObject]} pointerEvents="none&

随机推荐