Vue拖动指令

drag.js

import _ from "lodash";

class Drap {
  constructor(el, option = { parent: null }) {
    this.el = el;
    this.x = 0;
    this.y = 0;
    this.el.style.position = "absolute";
    // 父容器
    if (option?.parent) {
      this.container = document.getElementById(option.parent);
    } else {
      this.container = el.parentNode;
    }
    this.init();
  }
  init() {
    this.el.onmousedown = (e) => {
      e.stopPropagation();
      this.el.style.cursor = "move";
      this.el.style.zIndex = 999;
      this.el.style.userSelect = "none";
      this.lastLeft = this.el.offsetLeft;
      this.lastTop = this.el.offsetTop;
      this.x = e.clientX;
      this.y = e.clientY;

      this.container.onmousemove = (e) => {
        e.stopPropagation();
        e.preventDefault();
        const offsetX = e.clientX - this.x;
        let left = this.lastLeft + offsetX;
        if (offsetX < 0) {
          // 向左滑动
          if (left < 0) {
            left = 0;
          }
        } else {
          // 向右滑动
          if (left > this.container.offsetWidth - this.el.offsetWidth) {
            left = this.container.offsetWidth - this.el.offsetWidth;
          }
        }

        const offsetY = e.clientY - this.y;
        let top = this.lastTop + offsetY;
        if (offsetY < 0) {
          // 向上滑动
          if (top < 0) {
            top = 0;
          }
        } else {
          // 向下滑动
          if (top > this.container.offsetHeight - this.el.offsetHeight) {
            top = this.container.offsetHeight - this.el.offsetHeight;
          }
        }

        this.el.style.left = left + "px";
        this.el.style.top = top + "px";
      };

      document.onmouseup = (e) => {
        this.container.onmousemove = null;
        document.onmouseup = null;
        this.el.style.cursor = "pointer";
      };
    };
  }
}

export const drag = {
  mounted(el, binding) {
    new Drap(el, binding.value || {});
  },
};

main.js注册

import { createApp } from "vue";
import App from "./App.vue";
import { drag } from "./utils/drag";

const app = createApp(App);
app.directive("drag", drag);

组件使用

<div class="mapBox" id="mapBox">
    <div id="map" class="map"></div>
    <div class="search">
      <div v-drag="{ parent: 'mapBox' }" class="content">
        这是一个窗体
      </div>
    </div>
</div>
<style lang="less" scoped>
.mapBox {
  width: 100%;
  height: 100%;
  position: relative;

  .map {
    width: 100%;
    height: 100%;
  }

  .search {
    position: absolute;
    top: 0px;
    left: 0px;
    z-index: 100;

    .content {
      width: 430px;
      min-height: 385px;
      background-color: #fff;
    }
  }
}
</style>

 

posted @ 2023-01-03 10:29  卓扬  阅读(197)  评论(0编辑  收藏  举报