antd Modal组件拖动功能的一种实现方式

9 篇文章 0 订阅
8 篇文章 0 订阅

前言

对于一些弹窗组件,其中一个比较高的使用场景是拖拽功能。然而如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等其他库,实现方法同上述例子类似,不展开来讲解。
如有疑问,可以在评论区进行交流。也欢迎点赞⭐收藏 :)




拓展阅读:

  1. React + Router + Antd实现多标签页功能(具体代码实现)
  2. el-table行拖拽排序效果的实现(基于sortablejs)
  3. React + Antd实现动态切换主题功能
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值