<template> <div id="box" class="mainBox" @mousemove="move" @mouseup="moveEnd" :style="{ width: boxWidth + 'px', height: boxHeight + 'px', }" > <div id="node" @mousedown="moveStart" :style="{ left: nodeData.x + 'px', top: nodeData.y + 'px', }" class="node" ></div> </div> </template> <script> export default { data() { return { status: null, nodeData: { x: 10, y: 10, }, // 移动的起点——鼠标按下时鼠标的坐标 startX: null, startY: null, // 元素的初始位置 nodeX: null, nodeY: null, // 盒子的初始大小 boxWidth: 600, boxHeight: 300, // 盒子的坐标 boxX: null, boxY: null, }; }, mounted() { let boxDOM = document.getElementById("box"); this.boxX = boxDOM.clientLeft; this.boxY = boxDOM.clientTop; }, methods: { // 开始移动 moveStart(e) { if (e.target.id) { // 开启移动状态 this.status = "move"; // 获取鼠标初始坐标 this.startX = e.clientX; this.startY = e.clientY; // 获取元素的初始位置 let nodeDOM = document.getElementById("node"); this.nodeX = nodeDOM.offsetLeft; this.nodeY = nodeDOM.offsetTop; } }, // 移动中 move(e) { if (this.status === "move") { // 元素的新位置 = 初始位置+(鼠标当前的坐标 - 鼠标初始坐标) 【即鼠标移动的距离】 this.nodeData.x = this.nodeX + (e.clientX - this.startX); this.nodeData.y = this.nodeY + (e.clientY - this.startY); // 不能从左侧移出盒子 if (this.nodeData.x < this.boxX) { this.nodeData.x = this.boxX; } // 不能从顶部移出盒子 if (this.nodeData.y < this.boxY) { this.nodeData.y = this.boxY; } // 盒子大小随拖拽元素的位置自适应变化 this.boxWidth = this.nodeData.x + 200; this.boxHeight = this.nodeData.y + 200; } }, // 停止移动 moveEnd() { // 关闭移动状态 this.status = null; }, }, }; </script> <style scoped> .mainBox { margin: 30px; position: relative; border: 1px solid black; } .node { position: absolute; cursor: move; background: red; height: 100px; width: 100px; } </style>