【vue3】封装div可拖拽函数&边界限制

局部使用

<template>
    <div class="box" v-drag>
    </div>
</template>
   
<script setup lang='ts'>
import { Directive, ref } from "vue";//Directive自定义指令

let positionX = ref()
let positionY = ref()
const vMove: Directive = {
    mounted(el: HTMLElement) {
        // let moveEl = el.firstElementChild as HTMLElement;
        let moveEl = el as HTMLElement
        const mouseDown = (e: MouseEvent) => {
            //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
            鼠标点击物体那一刻相对于物体上边框的距离=点击时的位置相对于浏览器最上边的距离-物体上边框相对于浏览器最上边的距离
            console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft);
            let X = e.clientX - el.offsetLeft;//clientX 事件属性返回当事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平坐标
            let Y = e.clientY - el.offsetTop;
            const move = (e: MouseEvent) => {
                // 获取拖拽元素的位置
                let left = e.clientX - X;
                let top = e.clientY - Y;
                positionX.value = left
                positionY.value = top

                if (left <= 0) {
                    left = 0
                } else if (left >= document.documentElement.clientWidth - el.offsetWidth) {
                    left = document.documentElement.clientWidth - el.offsetWidth
                }

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

                el.style.left = left + "px";
                el.style.top = top + "px";
            };
            document.addEventListener("mousemove", move);
            document.addEventListener("mouseup", () => {
                document.removeEventListener("mousemove", move);
            });
        };
        moveEl.addEventListener("mousedown", mouseDown);
    },
};
</script>
   
<style scoped>
.box {
    position: fixed;
    left: 0;
    top: 0;
    width: 200px;
    height: 200px;
    background: pink;
}
</style>
  

全局使用

  • 在utils里面创建drag.ts文件

const drag = {
  mounted(el: HTMLElement) {
    let moveEl = el as HTMLElement
    const mouseDown = (e: MouseEvent) => {
      //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
      // console.log(e.clientX, e.clientY, "-----起始", el.offsetLeft);
      let X = e.clientX - el.offsetLeft;
      let Y = e.clientY - el.offsetTop;
      const move = (e: MouseEvent) => {
        // 获取拖拽元素的位置
        let left = e.clientX - X;
        let top = e.clientY - Y;

        if (left <= 0) {
          left = 0
        } else if (left >= document.documentElement.clientWidth - el.offsetWidth) {
          left = document.documentElement.clientWidth - el.offsetWidth
        }

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

        el.style.left = left + "px";
        el.style.top = top + "px";
      };
      document.addEventListener("mousemove", move);
      document.addEventListener("mouseup", () => {
        document.removeEventListener("mousemove", move);
      });
    };
    moveEl.addEventListener("mousedown", mouseDown);
  },
}

const directives = {
  install: function (app: any) {
    app.directive('drag', drag)
  }
}
export default directives

在main.ts里面全局引入

import Drag from "./util/drag"
const app = createApp(App)
app.use(Drag) 

在要使用的.vue直接 v-drag

<template>
    <div class="box" v-drag>
    </div>
</template>

<style scoped>
.box {
    position: fixed;
    left: 0;
    top: 0;
    width: 200px;
    height: 200px;
    background: pink;
}
</style>
  

来源

猜你喜欢

转载自blog.csdn.net/m0_67986791/article/details/129662175