vue实现鼠标框选
Vue 实现鼠标框选功能
基本思路
鼠标框选功能通常需要监听鼠标的按下、移动和释放事件,记录起始点和当前位置,动态计算选区范围并高亮显示。在Vue中可以通过指令或组件封装实现。
核心实现步骤
模板部分
<template>
<div
class="container"
@mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
>
<div
v-if="isSelecting"
class="selection-box"
:style="{
left: selectionBox.left + 'px',
top: selectionBox.top + 'px',
width: selectionBox.width + 'px',
height: selectionBox.height + 'px'
}"
></div>
<!-- 可选中的元素 -->
<div
v-for="item in items"
:key="item.id"
class="selectable-item"
:class="{ selected: isItemSelected(item) }"
>
{{ item.name }}
</div>
</div>
</template>
脚本部分
export default {
data() {
return {
isSelecting: false,
startPos: { x: 0, y: 0 },
currentPos: { x: 0, y: 0 },
selectionBox: { left: 0, top: 0, width: 0, height: 0 },
items: [
{ id: 1, name: 'Item 1', x: 10, y: 10, width: 100, height: 50 },
// 更多元素...
],
selectedItems: []
}
},
methods: {
handleMouseDown(e) {
this.isSelecting = true
this.startPos = { x: e.clientX, y: e.clientY }
this.currentPos = { ...this.startPos }
this.updateSelectionBox()
},
handleMouseMove(e) {
if (!this.isSelecting) return
this.currentPos = { x: e.clientX, y: e.clientY }
this.updateSelectionBox()
this.checkSelection()
},
handleMouseUp() {
this.isSelecting = false
},
updateSelectionBox() {
this.selectionBox = {
left: Math.min(this.startPos.x, this.currentPos.x),
top: Math.min(this.startPos.y, this.currentPos.y),
width: Math.abs(this.currentPos.x - this.startPos.x),
height: Math.abs(this.currentPos.y - this.startPos.y)
}
},
checkSelection() {
this.selectedItems = this.items.filter(item => {
const itemRect = {
left: item.x,
right: item.x + item.width,
top: item.y,
bottom: item.y + item.height
}
const selectionRect = {
left: this.selectionBox.left,
right: this.selectionBox.left + this.selectionBox.width,
top: this.selectionBox.top,
bottom: this.selectionBox.top + this.selectionBox.height
}
return !(
itemRect.right < selectionRect.left ||
itemRect.left > selectionRect.right ||
itemRect.bottom < selectionRect.top ||
itemRect.top > selectionRect.bottom
)
})
},
isItemSelected(item) {
return this.selectedItems.some(selected => selected.id === item.id)
}
}
}
样式部分
.container {
position: relative;
width: 100%;
height: 100vh;
background: #f5f5f5;
}
.selection-box {
position: absolute;
background: rgba(0, 120, 255, 0.2);
border: 1px solid rgba(0, 120, 255, 0.8);
}
.selectable-item {
position: absolute;
border: 1px solid #ccc;
padding: 10px;
background: white;
}
.selectable-item.selected {
background: #d4e6ff;
border-color: #0078ff;
}
进阶优化方向
性能优化 对于大量元素场景,可采用空间分区算法(如四叉树)优化碰撞检测性能。实现虚拟滚动减少DOM数量。
交互增强 添加Shift键多选支持。实现拖拽选择后的批量操作。添加选择框的缩放控制点。
边界处理 考虑滚动容器的情况,需将鼠标坐标转换为容器相对坐标。处理元素重叠时的z-index问题。
指令封装 将核心逻辑封装为Vue指令,便于复用:
Vue.directive('selectable', {
bind(el, binding) {
// 实现选择逻辑
}
})
以上实现提供了完整的鼠标框选功能基础,可根据实际需求进行调整和扩展。







