基于Ant Design的Modal组件来实现一个可拖拽的React模态框
写这篇文章的原因是因为在项目中用到了Antd Design的React组件,当有业务需求需要用到模态框的时候遇到了一些小问题,Antd的模态框Modal组件时不能拖拽的,一般情况下不可拖拽也没什么大的问题,但是遇到了客户提的需求,因此就想着在Modal组件原有的基础上进行扩展,封装一个可拖拽的模态框,当然我使用的这种方式不一定是最好的,所以仅仅是用于参考。
可以使用npm或yarn安装,可以直接使用下面的那段代码
npm install dragm
//OR
yarn add dragm
这是我安装之后直接复制了它的代码,你可以直接复制下面这段代码然后引入到自己项目中,而不需要在额外的安装
//DragM.js
import React from "react";
import PropTypes from "prop-types";
export default class DragM extends Reactponent {
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)`;
thisps.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 }=thisps;
const newStyle={ ...childrenps.style, cursor: "move", userSelect: "none" };
return React.cloneElement(React.Children.only(children), {
ref: tdom=> {
return (this.tdom=tdom);
},
style: newStyle
});
前提是你安装了Antd,同时记得修改DragM的路径
//MovableModal.js
import React, { Component } from "react";
import { Modal } from "antd";
import DragM from "./DragM";
class MovableModal extends Component {
render() {
const updateTransform=transformStr=> {
this.modalDom=document.getElementsByClassName("ant-modal-content")[0];
this.modalDom.style.transform=transformStr;
};
const { children, title, ...other }=thisps;
const mytitle=(
);
return (
{thisps.children}
);
export default MovableModal;
使用方式和Modal组件使用方式一样,没有增加则外的属性
visible={visible} title="你的标题" onOk={this.handleOk} onCancel={this.handleCancel} footer={[