本例基于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
实现效果