src/directives下index.js的文件配置
// 自定义指令
export default {
install(app) {
app.directive('drag', {
mounted(el, bind, vnode) { // 绑定的元素,绑定的值
// 这个事件主要是用于禁止选择网页中的文字
document.onselectstart = function () {
return false
}
el.onmousedown = function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
let disX = e.clientX
let disY = e.clientY
let offTop = e.target.offsetTop
let offLeft = e.target.offsetLeft
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离
let l = e.clientX - disX + offLeft
let t = e.clientY - disY + offTop
const width = document.querySelector('.list').clientWidth
const top = document.querySelector('.list').clientHeight
console.log(l,"llll");
console.log(t,"ttt");
if (l >= width - 70) {
l = width - 70
} else if (l <= 0) {
l = 0
}
if (t >= top - 70) {
t = top - 70
} else if (t <= 0) {
t = 0
}
el.style.left = l
el.style.top = t
bind.value.top = t
bind.value.left = l
}
document.onmouseup = function () {
document.onmousemove = null
document.onmouseup = null
}
return false
}
}
})
}
}
main.js文件中的配置
在.vue文件中的使用
<template>
<dl class="list">
<dd
v-for="(item, key) in totallist.list"
:key="key"
v-drag="item"
:style="{ left: item.left + 'px', top: item.top + 'px' }"
>
{{ item.title }}
<img
:src="item.img"
alt=""
/>
</dd>
</dl>
</template>
<script setup>
import { reactive } from "vue";
const totallist = reactive({
list: [
{
title: "张三",
img: "https://cdn.staticaly.com/gh/1024huijia/QingChunMeizi@master/10010.4i2i1hvz85k0.webp",
top: 50,
left: 80,
},
{
title: "李四",
img: "https://cdn.staticaly.com/gh/1024huijia/QingChunMeizi@master/10010.4i2i1hvz85k0.webp",
top: 80,
left: 50,
}
],
});
</script>
<style lang="less" scoped>
.list {
margin: 0 auto;
margin-top: 5px;
width: 340px;
height: 390px;
border: 1px solid red;
position: relative;
}
.list dd {
height: 70px;
width: 70px;
background-color: rgb(221, 221, 221);
margin: 0;
position: absolute;
}
.list dd img {
width: 50px;
height: 50px;
}
</style>
效果
vue自定义指令实现拖拽效果