vue3+ts 自定义指令v-drag

604 阅读1分钟

vue3的自定义指令,demo

// 鼠标位置-鼠标相对元素位置=元素位置

let left = e.clientX - disx;

let top = e.clientY - disy;

使用固定定位还有绝对定位(关键)

全部代码

<!--
 * @Descripttion: 自定义拖拽指令
 * @version: 
 * @Author: lihk
 * @Date: 2022-12-14 17:27:25
 * @LastEditors: lihk
 * @LastEditTime: 2022-12-15 10:17:34
-->
<template>
  <div class="conta">
    <div class="box" v-drag>
      <div class="header">头部</div>
      <div class="content">内容</div>
    </div>
  </div>

</template>

<script lang='ts' setup>
import { Directive, DirectiveBinding } from "vue-demi";

const vDrag: Directive<any, void> = (
  el: HTMLElement,
  bingding: DirectiveBinding
) => {
  let moveElement: HTMLDivElement = el.firstElementChild as HTMLDivElement;
  // console.log("el", moveElement);
  const mouseDown = (e: MouseEvent) => {
    var disx = e.pageX - el.offsetLeft;
    var disy = e.pageY - el.offsetTop;
    const move = (e: MouseEvent) => {
      // 鼠标位置-鼠标相对元素位置=元素位置
      let left = e.clientX - disx;
      let top = e.clientY - disy;
      // 限制拖拽范围不超出可视区
      if (left <= 0) {
        left = 5; // 设置成5,离边缘不要太近
      } else if (left > document.documentElement.clientWidth - el.clientWidth) {
        // document.documentElement.clientWidth屏幕可视区宽度
        left = document.documentElement.clientWidth - el.clientWidth - 5;
      }

      if (top <= 0) {
        top = 5;
      } else if (
        top >
        document.documentElement.clientHeight - el.clientHeight
      ) {
        top = document.documentElement.clientHeight - el.clientHeight - 5;
      }

      el.style.left = left + "px";
      el.style.top = top + "px";
    };
    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", () => {
      document.removeEventListener("mousemove", move);
    });
  };
  moveElement.addEventListener("mousedown", mouseDown);
};
</script>
<style lang='scss' scoped>
.conta {
  .box {
    position: absolute;
    .header {
      width: 100px;
      height: 30px;
      background-color: #000;
      color: #fff;
    }
    .content {
      width: 100px;
      height: 300px;
      border: 1px solid #e5e5e5;
    }
  }
}
</style>