一个简单的demo 能实现复制拖拽
<template>
<div class="drag" ref="drag">
<!-- <h2>使用拖拽实现移动和复制功能</h2> -->
<div ref="targtBox" draggable="true" id="copy" @dragstart='handler_dragstart' @dragend='dragend'>要复制的元素</div>
<div ref="back_box" id="copyTarget" @dragover='hander_dragover' @drop='handler_drop'>
<div class="targtBoxicon" draggable="true" @dragstart='dragstart($event,item)' @dragend='dragend_handler($event,item)' v-for="item,i in list" :key="i" :style="`left:${item.left}%;top:${item.top}%`">
{{i}}
</div>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
data() {
return {
startclientX_c: 0,
startclientY_c: 0,
bodyWidth: 0,//浏览器可视区域的宽高
bodyHeight: 0,
initWidth: 0, // 父元素的宽-自适应值
initHeight: 0, // 父元素的高-自适应值
startclientX: 0, // 元素拖拽前距离浏览器的X轴位置
startclientY: 0, //元素拖拽前距离浏览器的Y轴位置
elLeft: 0, // 元素的左偏移量
elTop: 0, // 元素的右偏移量
clone: null,//复制的元素
list: []
};
},
methods: {
// 页面初始化
initBodySize() {
this.initWidth = this.$refs.back_box.clientWidth; // 拿到父元素宽 背景盒子的宽高
this.initHeight = this.$refs.back_box.clientHeight;
this.bodyWidth = document.body.clientWidth // 浏览器的宽高
this.bodyHeight = document.body.clientHeight
},
handler_dragstart(event) {
console.log('拖拽开始', event.target.id, event);
// 设置数据
event.dataTransfer.setData('text/plain', event.target.id);
// 设置拖动效果 设置既复制又移动
event.effectAllowed = 'copyMove';
this.startclientX = event.clientX; // 记录拖拽元素初始位置 要处理一下
this.startclientY = event.clientY;
const target = event.target.cloneNode(true); // 复制拖拽的元素
this.clone = target; // 保存复制的元素
},
dragend(event) {
//计算偏移量
console.log(event, "结束位置")
let x = event.clientX - this.startclientX; // 计算偏移量
let y = event.clientY - this.startclientY;
const box = this.$refs.back_box; // 获取盒子元素
const rect = box.getBoundingClientRect(); // 获取盒子的位置信息
console.log('左边界位置:', rect.left);
// console.log('右边界位置:', rect.right);
console.log('顶部位置:', rect.top);
// console.log('底部位置:', rect.bottom);
let top = y - rect.top
let left = x
let eltop = Number(top / this.initHeight * 100).toFixed(2)
let elleft = Number(left / this.initWidth * 100).toFixed(2)
this.list.push({
left: elleft,
top: eltop
})
console.log(this.list)
event.dataTransfer.clearData();
},
//已有的数据拖动
dragstart(e, item) {
console.log(e, item, "子元素开始拖拽")
this.startclientX_c = e.clientX; // 记录拖拽元素初始位置
this.startclientY_c = e.clientY;
},
dragend_handler(e, item) {
console.log(e, item, "子元素结束拖拽")
console.log(item)
let x = e.clientX - this.startclientX_c; // 计算偏移量
let y = e.clientY - this.startclientY_c;
let top = 0, left = 0;
top += y
left += x
console.log(top, left, this.initHeight, this.initWidth)
let eltop = Number(top / this.initHeight * 100).toFixed(2)
let elleft = Number(left / this.initWidth * 100).toFixed(2)
console.log(eltop, elleft)
console.log(Number(item.top) + Number(eltop), Number(item.left) + Number(elleft))
item.top = Number(item.top) + Number(eltop)
item.left = Number(item.left) + Number(elleft)
// let left += y
// item.top += x;
// item.left +=y
console.log(item)
},
// 当被拖动元素在目标元素内时触发
hander_dragover(event) {
// console.log(event)
// event.target.style.background = 'lightblue';
event.preventDefault();
},
handler_drop(event) {
event.preventDefault();
},
handler_dragLeave(event) {
event.target.style.background = 'white';
event.preventDefault();
},
},
mounted() {
this.initBodySize()
},
};
</script>
<style scoped>
#copy,
#move {
border: 1px solid #000;
width: 100px;
height: 100px;
}
#copyTarget,
#moveTarget {
width: 50vw;
height: 50vh;
border: 1px solid #ff0000;
position: relative;
}
/* #newId {
width: 200px;
height: 50px;
border: 1px solid darkcyan;
} */
#targtBoxicon {
height: 20%;
width: 8%;
border: 1px solid darkcyan;
}
.targtBoxicon {
width: 100px;
height: 100px;
border: 1px solid darkcyan;
position: absolute;
}
</style>
```