创建一个功能文件
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.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); }, } const directives = { install: function (app: any) { app.directive('drag', drag) } } export default directives
标签页
<template> <div v-move class="box" style="text-align: right;"> {{ positionX }} {{ positionY }} </div> <div v-move class="box" style="text-align: right;"> {{ positionX }} {{ positionY }} </div> <div v-move class="box" style="text-align: right;"> {{ positionX }} {{ positionY }} </div> </template> <script setup lang='ts'> import { Directive, ref } from "vue"; let positionX = ref<number>(0) let positionY = ref<number>(0) 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; 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 lang='less' scoped> .box { position: fixed; left: 0; top: 0; width: 200px; height: 200px; border: 1px solid #ccc; background: red; .header { height: 20px; background: black; cursor: move; } } </style>
全局设置:main文件进行全局引入
import { createApp } from 'vue' // import './style.css' import App from './App.vue' import Drag from "./utils/drag.ts" createApp(App).use(Drag).mount('#app')