前言
对于一些弹窗组件,其中一个比较高的使用场景是拖拽功能。然而如antd的Modal
组件、element ui 的Dialog
组件等等其他UI,自带的弹窗却原生不支持拖拽功能,却是一大遗憾。
当然对于antd的Modal
组件,官方文档给出了一种基于react-draggable
来实现拖拽的效果:https://ant.design/components/modal-cn#components-modal-demo-modal-render 。
下面给出一种基于draggable
组件来实现拖拽效果的一种实现方法。
实现方法
关于draggable
draggable
给出的说明是:
High performance, fully cross browser, full featured drag and drop in a tiny (2k gzipped), dependency-free package.
高性能、跨浏览器、实现拖拽效果全功能的轻量级(压缩后只有2k)无依赖js库。
Github地址:https://github.com/bcherny/draggable
我们可以通过npm
或者 yarn
安装:
$ npm install draggable --save
draggable
的具体使用方法可以参看Github库的Readme文档,在此不展开赘述。
集成draggable
antd Modal
原生不支持拖拽,我们需要在Modal
打开后,初始化Draggable
组件。需要注意的是并不是每次Modal
打开都需要初始化Modal
,仅限于第一次打开Modal
后进行初始化即可。具体代码如下:
import React from "react";
import Draggable from "draggable";
import {
Button, Modal } from "antd";
import {
ModalProps } from "antd/lib/modal/Modal";
interface IState {
open: boolean;
draggableInited: boolean; // draggable初始化标识
}
export default class DraggableModal extends React.Component<
ModalProps,
IState
> {
constructor(props: ModalProps | Readonly<ModalProps>) {
super(props);
this.state = {
open: false,
draggableInited: false
};
}
showModal() {
this.setState({
open: true }, this.initDrag);
}
closeModal() {
this.setState({
open: false });
}
initDrag() {
// 仅限于首次打开,进行初始化draggable操作
if (!this.state.draggableInited) {
// 目标为:Modal组件
const ele = document.querySelector(".custom-draggable-modal");
new Draggable(ele, {
// 拖拽handle设置为Modal头部,不设置此参数表示整个Modal都可拖拽
handle: document.querySelector(".ant-modal-header")
});
// 初始化完成后,对draggableInited置于true
this.setState({
draggableInited: true });
}
}
render() {
return (
<div>
<Button type="primary" onClick={
() => this.showModal()}>
Open Modal
</Button>
<Modal
// 对Modal添加class:custom-draggable-modal
className="custom-draggable-modal"
open={
this.state.open}
onOk={
() => this.closeModal()}
onCancel={
() => this.closeModal()}
// Modal其他属性由父组件传入
{
...this.props}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</div>
);
}
}
实现效果
具体实现效果如下:
详细代码请移步至codesandbox:https://codesandbox.io/s/kind-thunder-nfu40p?file=/src/DraggableModal.tsx
后记
由于draggable
是一个纯js实现库,不依赖于其他第三方库,所以draggable
不仅仅用于react ui库,如:antd,也可用于vue/angular ui库如element ui等其他库,实现方法同上述例子类似,不展开来讲解。
如有疑问,可以在评论区进行交流。也欢迎点赞⭐收藏 :)
拓展阅读: