业务需要定位一个弹窗,然后随便拖动,不需要任何特效,然后我百度了一百遍,发现没有一个简单的功能,要么是复杂的换位置,拖拽可变大小,看起来就很重,于是我觉得还不如组件用指令搞一个,就几行代码的问题,不用在安装一个npm包了,最终写下了如下的代码。这里用到一个小技巧就是js里面定义变量,在css中使用,这个功能很实用vue3才有的,然后我这边分头部是支持可拖拽的,其它部分不拖拽。
<template>
<div v-move class="box">
<header class="header">
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
</div>
</template>
<script setup lang="ts">
import { Directive } from 'vue'
defineProps<{
width: string
height?: string
top?: string
left?: string
bgColor?: string
}>()
const vMove: Directive = {
mounted(el: HTMLElement) {
const moveEl = el.firstElementChild as HTMLElement
const mouseDown = (e: MouseEvent) => {
const innerWidth = window.innerWidth - el.clientWidth
const innerHeight = window.innerHeight - el.clientHeight
// 鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
const X = e.clientX - el.offsetLeft
const Y = e.clientY - el.offsetTop
const move = (e: MouseEvent) => {
if (e.clientX - X < 0) return
if (e.clientY - Y < 0) return
if (e.clientX - X > innerWidth) return
if (e.clientY - Y > innerHeight) return
el.style.left = e.clientX - X + 'px'
el.style.top = e.clientY - Y + 'px'
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move)
})
}
moveEl.addEventListener('mousedown', mouseDown)
}
}
</script>
<style lang="scss" scoped>
.box {
position: fixed;
left: v-bind(left);
top: v-bind(top);
width: v-bind(width);
height: v-bind(height);
background-color: v-bind(bgColor) ;
border-radius: 8px;
z-index: 1000;
.header {
min-height: 20px;
cursor: move;
}
}
</style>
使用时直接引入即可,方便快捷,在也不用加班了
import DragBox from '../../../../components/DragBox.vue'
<DragBox width="400px" top="100px" left="78%" v-show="isShowBox"></DragBox>
如果学到或者get了,麻烦贵手点下你的赞,谢谢~