当前位置:首页 > VUE

vue实现鼠标拖动多选

2026-02-22 12:06:31VUE

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

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

基础代码结构

<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。可以添加防抖处理减少不必要的计算。

vue实现鼠标拖动多选

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

完整组件示例

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

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

相关文章

css3怎么制作鼠标

css3怎么制作鼠标

使用CSS3制作鼠标样式 可以通过CSS的cursor属性自定义鼠标指针样式,结合伪元素或动画实现更复杂效果。 自定义系统预设指针 .element { cursor: pointer; /*…

vue实现拖动刻度

vue实现拖动刻度

实现拖动刻度功能 在Vue中实现拖动刻度功能可以通过结合原生HTML5的拖拽API和Vue的数据绑定特性来完成。以下是一个完整的实现方案: 基本实现思路 创建一个可拖动的滑块元素 监听鼠标事件处理拖…

vue实现组件拖动

vue实现组件拖动

Vue 实现组件拖动的几种方法 使用 HTML5 拖放 API HTML5 原生提供了拖放 API,可以通过 draggable 属性实现基础拖拽功能。在 Vue 中可以通过事件绑定实现交互逻辑。…

vue实现鼠标拖拽

vue实现鼠标拖拽

实现鼠标拖拽功能 在Vue中实现鼠标拖拽功能可以通过以下步骤完成。这里提供一个基础实现方案,适用于大多数拖拽场景。 监听鼠标事件 为需要拖拽的元素绑定mousedown、mousemove和mous…

vue实现拖动div

vue实现拖动div

实现拖动 div 的基本思路 在 Vue 中实现拖动 div 的功能,可以通过监听鼠标事件(mousedown、mousemove、mouseup)来动态更新元素的位置。核心逻辑是记录初始点击位置,计…

vue实现鼠标移入事件

vue实现鼠标移入事件

鼠标移入事件的基本实现 在Vue中实现鼠标移入事件可以通过v-on指令或@简写绑定mouseenter或mouseover事件。两者的区别在于事件冒泡机制: mouseenter:不会冒泡,仅在鼠标…