经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » React » 查看文章
react实现全局组件确认弹窗
来源:jb51  时间:2022/8/23 15:36:59  对本文有异议

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

创建全局modal组件

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

  1. import ReactDOM from 'react-dom';
  2. import React, { Fragment } from 'react';
  3. import Button from 'components/common/button';
  4. import Icon from 'components/common/icon';
  5. import css from './index.less';
  6.  
  7. export interface Props {
  8. ? isCancelIcon?: boolean;
  9. ? cancelText?: string;
  10. ? okText?: string;
  11. ? onCancel?: () => void;
  12. ? onOk?: () => void;
  13. ? footer?: React.ReactNode;
  14. ? style?: object;
  15. }
  16.  
  17. const Modal: React.FC<Props> = React.memo<Props>(({
  18. ? isCancelIcon, cancelText, okText, onOk, onCancel, footer, children, style
  19. }) => {
  20.  
  21. ? function renderBtn() {
  22. ? ? return (
  23. ? ? ? <Fragment>
  24. ? ? ? ? <Button?
  25. ? ? ? ? ? className={css.btn}
  26. ? ? ? ? ? onClick={() => onCancel()}
  27. ? ? ? ? >
  28. ? ? ? ? ? {cancelText}
  29. ? ? ? ? </Button>
  30. ? ? ? ? <Button?
  31. ? ? ? ? ? className={css.btn}?
  32. ? ? ? ? ? onClick={() => onOk()}?
  33. ? ? ? ? ? type="primary">
  34. ? ? ? ? ? {okText}
  35. ? ? ? ? </Button>
  36. ? ? ? </Fragment>
  37. ? ? );
  38. ? }
  39.  
  40. ? return (
  41. ? ? <div className={css.masker}>
  42. ? ? ? <div className={css.box} style={{ ...style }} >
  43. ? ? ? ? {isCancelIcon &&?
  44. ? ? ? ? <div?
  45. ? ? ? ? ? className={css.cancelIconBox}
  46. ? ? ? ? ? onClick={() => onCancel()}
  47. ? ? ? ? >
  48. ? ? ? ? ? <Icon className={css.cancelIcon} />
  49. ? ? ? ? </div>}
  50. ? ? ? ? {children}
  51. ? ? ? ? <div className={css.btnBox}>
  52. ? ? ? ? ? {footer || renderBtn()}
  53. ? ? ? ? </div>
  54. ? ? ? </div>
  55. ? ? </div>
  56. ? );
  57. });
  58.  
  59. Modal.defaultProps = {
  60. ? okText: '确定',
  61. ? cancelText: '取消',
  62. ? onCancel: () => {},
  63. ? onOk: () => {},
  64. ? isCancelIcon: true
  65. };
  66.  
  67. export default function ({ content, props }: { content: React.ReactNode; props: Props }) {
  68. ??
  69. ? const { onOk=() => {}, onCancel=() => {}, ...others } = props;
  70. ? /**
  71. ? ?* 取消操作,关闭弹窗
  72. ? ?*/
  73. ? function handleClose() {
  74. ? ? ReactDOM.unmountComponentAtNode(div);
  75. ? ? document.body.removeChild(div);
  76. ? ? onCancel();
  77. ? }
  78. ? /**
  79. ? ?* 确认操作,关闭弹窗
  80. ? ?*/
  81. ? function handleOk() {
  82. ? ? ReactDOM.unmountComponentAtNode(div);
  83. ? ? document.body.removeChild(div);
  84. ? ? onOk();
  85. ? }
  86.  
  87. ? let div = document.createElement('div');
  88. ? document.body.appendChild(div);
  89. ? ReactDOM.render(
  90. ? ? <Modal?
  91. ? ? ? {...others}
  92. ? ? ? onOk={handleOk}?
  93. ? ? ? onCancel={handleClose}
  94. ? ? >
  95. ? ? ? {content}
  96. ? ? </Modal>,
  97. ? ? div);
  98.  
  99. ? return {
  100. ? ? handleOk: () => handleOk(),
  101. ? ? handleClose: () => handleClose()
  102. ? };
  103. }

less文件

  1. @import '~common/less/index.less';
  2. ? .masker{
  3. ? ? width: 100vw;
  4. ? ? height: 100vh;
  5. ? ? background: @mask-color;
  6. ? ? position: fixed;
  7. ? ? left: 0;
  8. ? ? top: 0;
  9. ? ? display: flex;
  10. ? ? justify-content: center;
  11. ? ? flex-direction: column;
  12. ? ? align-items: center;
  13. ? ? overflow: hidden;
  14. ? ? .box{
  15. ? ? ? width: 500px;
  16. ? ? ? height: 230px;
  17. ? ? ? position: relative;
  18. ? ? ? background-color: white;
  19. ? ? ? position: relative;
  20. ? ? ? transition: .2s;
  21. ? ? ? animation: showModal .2s ease-in forwards;
  22. ? ? ? .cancelIconBox{
  23. ? ? ? ? width: 27px;
  24. ? ? ? ? height: 27px;
  25. ? ? ? ? line-height: 27px;
  26. ? ? ? ? text-align: center;
  27. ? ? ? ? position: absolute;
  28. ? ? ? ? right: 15px;
  29. ? ? ? ? top: 22px;
  30. ? ? ? ? cursor: pointer;
  31. ? ? ? ? .cancelIcon{
  32. ? ? ? ? ? .font(17px)
  33. ? ? ? ? }
  34. ? ? ? }
  35. ? ? ? .btnBox{
  36. ? ? ? ? width: 100%;
  37. ? ? ? ? position: absolute;
  38. ? ? ? ? left: 0;
  39. ? ? ? ? bottom: 20px;
  40. ? ? ? ? padding-right: 10px;
  41. ? ? ? ? display: flex;
  42. ? ? ? ? flex-flow: row;
  43. ? ? ? ? justify-content: flex-end;
  44. ? ? ? ? align-items: center;
  45. ? ? ? ? ? .btn{
  46. ? ? ? ? ? ? margin-right: 10px;
  47. ? ? ? ? ? ? .font(12px)
  48. ? ? ? ? ? }
  49. ? ? ? ? }
  50. ? ? }
  51. ? }
  52.  
  53. ? @keyframes showModal {
  54. ? ? 0%{
  55. ? ? ? transform:translate(-100px, 60px) scale(.5) ;
  56. ? ? }
  57. ? ? 100%{
  58. ? ? ? transform:translate(0, 0) scale(1) ?;
  59. ? ? }
  60. ? }

确认框内容组件

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

tsx文件

  1. import React from 'react';
  2. import classNames from 'classnames';
  3. import Icon from 'components/common/icon';
  4. import modal, { Props as ModalProps } from '../components/modal';
  5. import css from './index.less';
  6.  
  7. interface Content {
  8. ? key: string;
  9. ? value: string;
  10. }
  11.  
  12. export interface Props extends ModalProps {
  13. ? title?: string;
  14. ? content?: Content[];
  15. }
  16.  
  17. export default function success({ title, content, ...others }: Props) {
  18.  
  19. ? const node = (
  20. ? ? <div className={css.successWrap}>
  21. ? ? ? <div className={css.line} />
  22. ? ? ? <div className={css.content}>
  23. ? ? ? ? <Icon className={css.successIcon} />
  24. ? ? ? ? <div className={css.right}>
  25. ? ? ? ? ? <span className={css.successTitle}>{title}</span>
  26. ? ? ? ? ? {
  27. ? ? ? ? ? ? content && content.map((item, index) => {
  28. ? ? ? ? ? ? ? return (
  29. ? ? ? ? ? ? ? ? <div key={`content_${index}`} className={css.contentList}>
  30. ? ? ? ? ? ? ? ? ? <div className={css.key}>{item.key}:</div>
  31. ? ? ? ? ? ? ? ? ? <span>{item.value}</span>
  32. ? ? ? ? ? ? ? ? </div>
  33. ? ? ? ? ? ? ? );
  34. ? ? ? ? ? ? })
  35. ? ? ? ? ? }
  36. ? ? ? ? </div>
  37. ? ? ? </div>
  38. ? ? </div>
  39. ? );
  40.  
  41. ? modal({
  42. ? ? content: node,
  43. ? ? props: others
  44. ? });
  45. }

less文件

  1. @import '~common/less/index.less';
  2. ? .successWrap{
  3. ? ? .line{
  4. ? ? ? width: 100%;
  5. ? ? ? height: 8px;
  6. ? ? ? background-color: #6EA204;
  7. ? ? }
  8. ? ? .content{
  9. ? ? ? display: flex;
  10. ? ? ? flex-flow: row;
  11. ? ? ? margin: 30px 0 0 40px;
  12. ? ? ? .successIcon{
  13. ? ? ? ? .font(72px);
  14. ? ? ? }
  15. ? ? ? .right{
  16. ? ? ? ? display: flex;
  17. ? ? ? ? flex-flow: column;
  18. ? ? ? ? padding-top: 10px;
  19. ? ? ? ? margin-left: 20px;
  20. ? ? ? ? .successTitle{
  21. ? ? ? ? ? .contentList();
  22. ? ? ? ? ? .font(18px);
  23. ? ? ? ? ? font-weight:500;
  24. ? ? ? ? }
  25. ? ? ? ? .contentList{
  26. ? ? ? ? ? display: flex;
  27. ? ? ? ? ? flex-flow: row;
  28. ? ? ? ? ? .font(12px);
  29. ? ? ? ? ? font-weight:400;
  30. ? ? ? ? ? color:@font-title-color;
  31. ? ? ? ? ? margin-bottom: 7px;
  32. ? ? ? ? ? .key{
  33. ? ? ? ? ? ? min-width: 72px;
  34. ? ? ? ? ? }
  35. ? ? ? ? }
  36. ? ? ? }
  37. ? ? }
  38. ? }

使用全局确认框

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

  1. import React from 'react';
  2. import success from 'components/common/confirm/success';
  3. const content = [
  4. ? {?
  5. ? ? key: '代理商姓名',
  6. ? ? value: '东东东'
  7. ? },
  8. ? {?
  9. ? ? key: '联系方式',
  10. ? ? value: '18978765678'
  11. ? },
  12. ? {?
  13. ? ? key: '代理商账号',
  14. ? ? value: '这是一个测试登录用户名'
  15. ? },
  16. ? {?
  17. ? ? key: '初始密码',
  18. ? ? value: '这是一个测试登录用户名'
  19. ? },
  20. ];
  21. export interface Props {}
  22. const Components: React.FC<Props> = () => {
  23.  
  24. return (
  25. ?<Button onClick={() => success({?
  26. ?content, title: '代理商录入成功',?
  27. ?okText: '继续录入',?
  28. ?cancelText: '返回列表'?
  29. ?})}
  30. ?>成功状态框</Button>
  31. )
  32.  
  33. Components.defaultProps = {};
  34.  
  35. export default Components

实现效果

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号