拖拽代码实现如下:
<template>
<div
class="wrapper"
ref="draggableBox"
@mousedown="startDrag"
>
<div v-resize class="resize-box"></div>
</div>
</template>
<script setup>
import { ref, shallowRef, onBeforeUnmount, reactive } from "vue";
const draggableBox = ref(null);
let isDragging = false;
let offsetX, offsetY;
const startDrag = (e) => {
isDragging = true;
offsetX = e.clientX - draggableBox.value.getBoundingClientRect().left;
offsetY = e.clientY - draggableBox.value.getBoundingClientRect().top;
document.addEventListener('mousemove', handleDrag);
document.addEventListener('mouseup', stopDrag);
};
const handleDrag = (e) => {
if (!isDragging) return;
const left = e.clientX - offsetX;
const top = e.clientY - offsetY;
draggableBox.value.style.left = `${left}px`;
draggableBox.value.style.top = `${top}px`;
};
const stopDrag = () => {
isDragging = false;
document.removeEventListener('mousemove', handleDrag);
document.removeEventListener('mouseup', stopDrag);
};
</script>
<style lang="less" scoped>
.content {
font-weight: 600;
color: #999;
}
.table-cell {
margin-top: 8px;
}
.title {
color: #333;
}
.editor {
display: none;
}
.wrapper {
width: 100px;
background: #e3e3e3;
position: absolute;
}
.resize-box {
width: 100px;
height: 100px;
background: #333;
position: absolute;
resize: both; /* 允许水平和垂直调整大小 */
overflow: auto; /* 显示滚动条以处理缩小的内容 */
}
</style>
缩放采用自定义指令形式去实现:
app.directive('resize', {
mounted(el, binding) {
// 这里是指令绑定到元素上后执行的逻辑
const resizableDiv = el;
let isResizing = false;
let initialMouseX;
let initialWidth;
resizableDiv.addEventListener('mousedown', function (e) {
isResizing = true;
initialMouseX = e.clientX;
initialWidth = parseFloat(getComputedStyle(resizableDiv, null).getPropertyValue('width'));
resizableDiv.style.userSelect = 'none'; // 防止文字选中
});
window.addEventListener('mousemove', function (e) {
if (!isResizing) return;
const width = initialWidth + (e.clientX - initialMouseX);
resizableDiv.style.width = `${width}px`;
e.preventDefault()
e.stopPropagation()
});
window.addEventListener('mouseup', function () {
isResizing = false;
resizableDiv.style.removeProperty('user-select');
});
},
})面就行