用vue2实现可拖拽的对话框限制对话框在可视区域内的拖动、允许用户关闭它
以下是一个简单的实现可拖拽的对话框的Vue组件示例:
<template>
<div class="dialog" :style="{ top: top + 'px', left: left + 'px' }">
<div class="header" @mousedown="startDrag">
<span>{{ title }}</span>
<button @click="close">X</button>
</div>
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: 'Dialog'
},
x: {
type: Number,
default: 0
},
y: {
type: Number,
default: 0
}
},
data() {
return {
isDragging: false,
dragStartX: 0,
dragStartY: 0,
left: this.x,
top: this.y
}
},
methods: {
startDrag(event) {
this.isDragging = true
this.dragStartX = event.clientX
this.dragStartY = event.clientY
},
stopDrag() {
this.isDragging = false
},
drag(event) {
if (this.isDragging) {
const deltaX = event.clientX - this.dragStartX
const deltaY = event.clientY - this.dragStartY
const newX = this.left + deltaX
const newY = this.top + deltaY
const maxX = window.innerWidth - this.$el.clientWidth
const maxY = window.innerHeight - this.$el.clientHeight
this.left = Math.min(Math.max(newX, 0), maxX)
this.top = Math.min(Math.max(newY, 0), maxY)
this.dragStartX = event.clientX
this.dragStartY = event.clientY
}
},
close() {
this.$emit('close')
}
},
mounted() {
document.addEventListener('mousemove', this.drag)
document.addEventListener('mouseup', this.stopDrag)
},
beforeDestroy() {
document.removeEventListener('mousemove', this.drag)
document.removeEventListener('mouseup', this.stopDrag)
}
}
</script>
<style>
.dialog {
position: absolute;
border: 1px solid #ccc;
background-color: #fff;
z-index: 100;
width: 400px;
height: 300px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
background-color: #eee;
}
.content {
padding: 8px;
}
</style>
在这个组件中,我们使用了props传递标题和初始位置,使用data管理状态,使用methods处理拖动和关闭事件。在mounted和beforeDestroy生命周期钩子中,我们添加和移除了全局的mousemove和mouseup事件监听器来处理拖动事件。
在startDrag方法中,我们设置了isDragging状态为true,并记录下鼠标的起始位置。在drag方法中,我们计算出拖动的偏移量,并根据偏移量更新对话框的位置。我们还使用Math.min和Math.max方法限制对话框在可视区域内的拖动。
最后,在close方法中,我们使用$emit方法触发一个close事件,以便父组件能够接收到对话框关闭的消息。
使用这个组件非常简单,只需要在父组件中引入它并使用v-if指令来控制它的显示和隐藏即可:
<template>
<div>
<button @click="showDialog">Show dialog</button>
<MyDialog v-if="dialogVisible" @close="closeDialog">
<p>Hello, world!</p>
</MyDialog>
</div>
</template>
<script>
import MyDialog from './MyDialog'
export default {
components: {
MyDialog
},
data() {
return {
dialogVisible: false
}
},
methods: {
showDialog() {
this.dialogVisible = true
},
closeDialog() {
this.dialogVisible = false
}
}
}
</script>
``
原文地址: https://www.cveoy.top/t/topic/g1fB 著作权归作者所有。请勿转载和采集!