基於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組件使用方式一樣,沒有增加則外的屬性

  <MovableModal

  visible={visible}

  title="你的標題"

  onOk={this.handleOk}

  onCancel={this.handleCancel}

  footer={[

  ,

  <Button

  key="submit"

  type="primary"

  loading={loading}

  onClick={this.handleOk}

  >

  提交

  >

  具體的相關事件需要自己處理,也就是控制模態框顯隱等。

  這個方法目前發現的不足的地方就是在打開移動,然會關閉再打開就會發現位置保持在移動后的外置,因此需要在關閉后自己手動處理相關的屬性。暫未發現明顯的bug。

  本方法算是比較暴力的一個方法了,從結果來看基本滿足客戶需求,當然也有不足的地方,如果大家有更好的解決方案,歡迎到評論區留言。如果本文對你有幫助,請記得幫忙轉發、點贊加關注哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM