以下是一个简单的实现可拖拽的对话框的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处理拖动和关闭事件。在mountedbeforeDestroy生命周期钩子中,我们添加和移除了全局的mousemovemouseup事件监听器来处理拖动事件。

startDrag方法中,我们设置了isDragging状态为true,并记录下鼠标的起始位置。在drag方法中,我们计算出拖动的偏移量,并根据偏移量更新对话框的位置。我们还使用Math.minMath.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>
``
用vue2实现可拖拽的对话框限制对话框在可视区域内的拖动、允许用户关闭它

原文地址: https://www.cveoy.top/t/topic/g1fB 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录