当前位置:首页 > VUE

vue实现鼠标拖动多选

2026-02-22 12:06:31VUE

vue实现鼠标拖动多选

实现鼠标拖动多选的核心思路

监听鼠标的mousedownmousemovemouseup事件,通过计算鼠标移动轨迹和位置,动态生成一个选择框。检测目标元素是否在选择框范围内,更新选中状态。

vue实现鼠标拖动多选

基础代码结构

<template>
  <div 
    class="container"
    @mousedown="startDrag"
    @mousemove="onDrag"
    @mouseup="endDrag"
  >
    <div 
      v-for="item in items" 
      :key="item.id"
      class="selectable-item"
      :class="{ selected: selectedItems.includes(item.id) }"
    >
      {{ item.name }}
    </div>
    <div 
      v-if="isDragging"
      class="selection-box"
      :style="selectionBoxStyle"
    />
  </div>
</template>

数据与事件处理

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
        // 更多项目...
      ],
      selectedItems: [],
      isDragging: false,
      startPos: { x: 0, y: 0 },
      currentPos: { x: 0, y: 0 }
    }
  },
  computed: {
    selectionBoxStyle() {
      const left = Math.min(this.startPos.x, this.currentPos.x)
      const top = Math.min(this.startPos.y, this.currentPos.y)
      const width = Math.abs(this.currentPos.x - this.startPos.x)
      const height = Math.abs(this.currentPos.y - this.startPos.y)

      return {
        left: `${left}px`,
        top: `${top}px`,
        width: `${width}px`,
        height: `${height}px`
      }
    }
  },
  methods: {
    startDrag(e) {
      this.isDragging = true
      this.startPos = { x: e.clientX, y: e.clientY }
      this.currentPos = { x: e.clientX, y: e.clientY }
    },
    onDrag(e) {
      if (!this.isDragging) return
      this.currentPos = { x: e.clientX, y: e.clientY }
      this.updateSelection()
    },
    endDrag() {
      this.isDragging = false
    }
  }
}
</script>

碰撞检测实现

methods: {
  updateSelection() {
    const selectionBox = {
      left: Math.min(this.startPos.x, this.currentPos.x),
      top: Math.min(this.startPos.y, this.currentPos.y),
      right: Math.max(this.startPos.x, this.currentPos.x),
      bottom: Math.max(this.startPos.y, this.currentPos.y)
    }

    this.selectedItems = []
    const items = document.querySelectorAll('.selectable-item')

    items.forEach(item => {
      const rect = item.getBoundingClientRect()
      const isIntersecting = !(
        selectionBox.right < rect.left || 
        selectionBox.left > rect.right || 
        selectionBox.bottom < rect.top || 
        selectionBox.top > rect.bottom
      )

      if (isIntersecting) {
        const itemId = parseInt(item.dataset.id)
        this.selectedItems.push(itemId)
      }
    })
  }
}

样式优化

<style>
.container {
  position: relative;
  width: 100%;
  height: 100vh;
}

.selectable-item {
  position: absolute;
  width: 100px;
  height: 100px;
  border: 1px solid #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
}

.selectable-item.selected {
  background-color: rgba(0, 123, 255, 0.3);
  border-color: #007bff;
}

.selection-box {
  position: absolute;
  background-color: rgba(0, 123, 255, 0.1);
  border: 1px dashed #007bff;
  pointer-events: none;
}
</style>

性能优化建议

使用事件委托减少事件监听器数量,避免在mousemove中频繁操作DOM。可以添加防抖处理减少不必要的计算。

methods: {
  onDrag: _.throttle(function(e) {
    if (!this.isDragging) return
    this.currentPos = { x: e.clientX, y: e.clientY }
    this.updateSelection()
  }, 50)
}

完整组件示例

将上述代码整合为一个完整组件,确保所有功能协同工作。注意处理边界情况,如滚动容器、元素重叠等场景。

标签: 鼠标拖动
分享给朋友:

相关文章

js实现 拖动

js实现 拖动

实现拖动的步骤 HTML 结构 创建一个可拖动的元素和一个放置区域: <div id="draggable" draggable="true">拖动我</div> <d…

vue实现拖动栏

vue实现拖动栏

Vue 实现拖动栏 使用 HTML5 拖放 API HTML5 提供了原生的拖放 API,可以直接在 Vue 中使用。通过 draggable 属性标记可拖动元素,并监听 dragstart、drag…

vue实现拖动功能

vue实现拖动功能

使用HTML5拖放API实现基础拖动 Vue中可以通过HTML5原生拖放API实现基础拖动功能。在元素上添加draggable="true"属性使其可拖动,通过@dragstart事件设置被拖拽数据。…

vue实现拖动文件移动

vue实现拖动文件移动

Vue 实现文件拖动移动 实现文件拖动移动功能通常涉及 HTML5 的拖放 API 和 Vue 的事件处理。以下是具体实现方法: 基础拖放实现 在 Vue 组件中设置拖放区域并处理相关事件: &l…

vue实现鼠标双击事件

vue实现鼠标双击事件

Vue 实现鼠标双击事件的方法 在 Vue 中实现鼠标双击事件可以通过多种方式完成,以下是常见的几种方法: 使用 @dblclick 指令 Vue 提供了 @dblclick 指令,可以直接在模板中…

vue实现拖动放大缩小

vue实现拖动放大缩小

实现拖动放大缩小的基本思路 在Vue中实现元素的拖动和放大缩小功能,通常需要结合鼠标事件和CSS变换。通过监听鼠标的按下、移动和释放事件,计算元素的位移和缩放比例,最终应用到元素的transform属…