1、效果如下
2、如下两个文件不需要修改
drag.js
import React from "react";
import PropTypes from "prop-types";
export default class DragM extends React.Component {
static propTypes = {
children: PropTypes.element.isRequired
};
static defaultProps = {
//默认是移动children dom,覆盖该方法,可以把tranform行为同步给外部
updateTransform: (transformStr, tx, ty, tdom) => {
tdom.style.transform = transformStr;
}
};
position = {
startX: 0,
startY: 0,
dx: 0,
dy: 0,
tx: 0,
ty: 0
};
start = event => {
if (event.button != 0) {
//只允许左键,右键问题在于不选择conextmenu就不会触发mouseup事件
return;
}
document.addEventListener("mousemove", this.docMove);
this.position.startX = event.pageX - this.position.dx;
this.position.startY = event.pageY - this.position.dy;
};
docMove = event => {
const tx = event.pageX - this.position.startX;
const ty = event.pageY - this.position.startY;
const transformStr = `translate(${tx}px,${ty}px)`;
this.props.updateTransform(transformStr, tx, ty, this.tdom);
this.position.dx = tx;
this.position.dy = ty;
};
docMouseUp = event => {
document.removeEventListener("mousemove", this.docMove);
};
componentDidMount() {
this.tdom.addEventListener("mousedown", this.start);
//用document移除对mousemove事件的监听
document.addEventListener("mouseup", this.docMouseUp);
}
componentWillUnmount() {
this.tdom.removeEventListener("mousedown", this.start);
document.removeEventListener("mouseup", this.docMouseUp);
document.removeEventListener("mousemove", this.docMove);
}
render() {
const {children} = this.props;
const newStyle = {
...children.props.style,
cursor: "move",
userSelect: "none"
};
return React.cloneElement(React.Children.only(children), {
ref: tdom => {
return (this.tdom = tdom);
},
style: newStyle
});
}
}
index.js
import React from "react";
import PropTypes from "prop-types";
import DragM from "./drag";
import {Modal} from "antd";
class BuildTitle extends React.Component {
updateTransform = transformStr => {
this.modalDom.style.transform = transformStr;
};
componentDidMount() {
const modalList = document.getElementsByClassName("ant-modal"); //modal的class是ant-modal
this.modalDom = modalList[modalList.length - 1];
}
render() {
const {title} = this.props;
return (
<DragM updateTransform={this.updateTransform}>
<div>{title}</div>
</DragM>
);
}
}
export default class DragModal extends React.Component {
static propTypes = {
drag: PropTypes.bool,
destroyOnClose: PropTypes.bool
};
static defaultProps = {
drag: true,
destroyOnClose: true
};
render() {
const {
drag,
visible,
title,
destroyOnClose,
children,
...restProps
} = this.props;
//是否可拖拽
const _title =
title && drag ? (
<BuildTitle visible={visible} title={title}/>
) : (
title
);
return (
<Modal
visible={visible}
title={_title}
destroyOnClose={destroyOnClose}
{...restProps}
>
{children}
</Modal>
);
}
}
3、如下两个文件,自己适当修改接口数据来源即可
index.js
import React from "react";
import styles from "./index.less";
import {Badge, Icon, Tabs} from "antd";
import DragModal from "../DragModal";
import classNames from 'classnames';
import NHFetch from "../../../../utils/NHFetch";
const TabPane = Tabs.TabPane;
export default class ModalContent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: undefined,
open: true
};
}
componentDidMount() {
this.getMessage();
}
componentDidUpdate(prevProps) {
// 当props.params变化时获取新数据
if (this.props.params !== prevProps.params) {
console.log('----------------------------------------')
this.getMessage();
}
}
getMessage = () => {
let xsid = this.props.params
if (xsid) {
NHFetch('api/zhxg-yxwz/shxd/getZzbdInfoList', 'get', {xsid: xsid}).then((res) => {
if (res && res.code === 200) {
this.setState({data: res.data});
}
})
}
}
// 切换状态
onChangeOpen = () => {
this.setState({
open: !this.state.open
});
};
render() {
const {data, open} = this.state;
const {studentName} = this.props
return (
<DragModal
className={classNames({
[styles.modalClese]: !open
})}
wrapClassName={styles.dragWrap}
closable={false}
width={300}
title={
<div>
{studentName + ":"}自助报道办理情况
<div
className={styles.modalBtn}
onClick={this.onChangeOpen}
>
{open ? <Icon type="down"/> : <Icon type="up"/>}
</div>
</div>
}
mask={false}
visible={this.props.params}
footer={false}
>
<div className={styles.modalContent}>
{
data && data.map((item, i) => {
return (
<div key={i} className={styles.modalListHeader}>
<Badge status={item.BLZT === '1' ? "success" : "processing"}/>
{item.HJMC + " "}
<span style={item.BLZT === '1' ? {color: "green"} : {color: 'red'}}>
{item.BLZT === '1' ? '已办理' : "未办理"}
</span>
</div>
);
})
}
</div>
</DragModal>
);
}
}
css文件,index.less
.box {
background-color: #fff;
.danger {
color: #f5222d
}
.primary {
color: #1990ff
}
}
/* 页签 */
.tabs {
:global {
.ant-tabs-bar {
margin-bottom: 0;
}
.ant-tabs-tab {
margin-right: 0;
}
.ant-badge {
margin-left: 4px;
margin-top: -4px;
}
.ant-badge-count {
height: 16px;
line-height: 16px;
}
.ant-badge-multiple-words {
padding: 0 4px;
}
}
.tabsExtra {
:global {
.ant-input {
width: 270px;
}
.ant-btn {
width: 80px;
margin-left: 10px;
}
.ant-select-selection {
border: none;
box-shadow: none;
}
}
}
}
/* 菜单 */
.menuLayout {
&:global(.ant-layout) {
background: #fff;
}
:global {
.ant-layout-sider {
box-shadow: 2px 0 4px 0 rgba(217, 217, 217, 0.5);
}
.ant-layout-content {
padding: 10px;
}
}
}
.menu {
padding: 10px 0;
:global {
.ant-menu-item {
width: 100%;
margin-top: 0;
margin-bottom: 0 !important;
&:after {
right: inherit;
left: 0;
}
}
}
}
/* 表格 */
.tableTop {
overflow: hidden;
.tableTopLeft {
float: left;
button {
margin-right: 10px;
}
}
.tableTopRight {
float: right;
}
}
.table {
margin-top: 10px;
.audit {
position: absolute;
left: -70px;
top: 50%;
width: 80px;
height: 56px;
margin-top: -28px;
pointer-events: none
}
:global {
.ant-table-thead {
position: relative;
height: 50px;
&:after {
content: "";
display: block;
position: absolute;
left: 0;
right: 0;
top: 42px;
background-color: #fff;
height: 10px;
}
tr {
background: rgba(25, 144, 255, 0.2);
&:first-child > th:first-child {
border-top-left-radius: 0;
}
&:first-child > th:last-child {
border-top-right-radius: 0;
}
}
th {
padding: 10px;
height: 50px;
padding-bottom: 20px;
white-space: nowrap;
}
}
.ant-table-tbody {
border-left: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
tr:first-child td {
border-top: 1px solid #e8e8e8;
}
tr > td {
position: relative;
&:after {
content: "";
position: absolute;
right: 0;
top: 16px;
bottom: 16px;
border-right: 1px solid #e8e8e8;
}
&:last-child,
&:first-child {
&:after {
display: none;
}
}
}
}
}
}
.tablePage {
overflow: hidden;
margin-top: 10px;
padding: 0 10px;
.tablePageLeft {
float: left;
color: #999;
line-height: 32px;
}
.tablePageRight {
float: right;
}
}
/* 弹窗 */
.dragWrap {
overflow: hidden;
pointer-events: none;
.modalBtn {
position: absolute;
top: 0;
right: 0;
height: 50px;
width: 50px;
text-align: center;
line-height: 50px;
cursor: pointer;
user-select: none;
}
.modalClese {
:global {
.ant-modal-body {
height: 0;
}
}
}
.modalContent {
width: 300px;
padding: 0 20px 10px 20px;
}
.modalListHeader {
padding: 10px;
}
.modalListItem {
position: relative;
padding: 5px 30px 5px 23px;
background-color: rgba(25, 144, 255, 0.05);
border-radius: 8px;
margin-bottom: 6px;
}
.modalItemBadge {
position: absolute;
left: 10px;
top: 5px;
}
.itemInfo {
font-size: 12px;
color: #999;
span {
color: #1990ff;
}
}
.modalItemIcon {
position: absolute;
right: 10px;
top: 50%;
margin-top: -15px;
color: #1990ff;
font-size: 20px;
}
:global {
.ant-modal {
position: absolute;
top: auto;
bottom: 0;
right: 0;
margin: 0;
padding-bottom: 0;
pointer-events: auto;
}
.ant-modal-header {
padding: 14px 10px;
background-color: #1990ff;
.ant-modal-title {
padding-right: 50px;
color: #fff;
font-size: 14px;
}
}
.ant-modal-content {
overflow: hidden;
}
.ant-modal-close {
color: #fff;
}
.ant-modal-close-x {
height: 50px;
line-height: 50px;
}
.ant-modal-body {
max-height: 350px;
padding: 0;
overflow: hidden;
overflow-y: scroll;
margin-right: -20px;
transition: all 0.3s;
}
}
}
4、最后适当位置使用组件即可