vue实现鼠标框选
Vue 实现鼠标框选功能
核心思路
鼠标框选功能需要监听鼠标按下、移动和抬起事件,动态计算选区范围并高亮显示。Vue中可通过自定义指令或组件封装实现。
基础实现步骤
模板部分
<template>
<div
class="selection-area"
@mousedown="startSelection"
@mousemove="updateSelection"
@mouseup="endSelection"
>
<div
v-if="isSelecting"
class="selection-box"
:style="boxStyle"
/>
<!-- 可选内容区域 -->
<slot></slot>
</div>
</template>
脚本部分
export default {
data() {
return {
isSelecting: false,
startX: 0,
startY: 0,
currentX: 0,
currentY: 0
}
},
computed: {
boxStyle() {
const left = Math.min(this.startX, this.currentX)
const top = Math.min(this.startY, this.currentY)
const width = Math.abs(this.currentX - this.startX)
const height = Math.abs(this.currentY - this.startY)
return {
left: `${left}px`,
top: `${top}px`,
width: `${width}px`,
height: `${height}px`,
position: 'absolute',
backgroundColor: 'rgba(100, 180, 255, 0.3)',
border: '1px dashed #666'
}
}
},
methods: {
startSelection(e) {
this.isSelecting = true
this.startX = e.clientX
this.startY = e.clientY
this.currentX = e.clientX
this.currentY = e.clientY
},
updateSelection(e) {
if (!this.isSelecting) return
this.currentX = e.clientX
this.currentY = e.clientY
},
endSelection() {
this.isSelecting = false
// 此处可添加选中项处理逻辑
}
}
}
进阶功能实现
元素碰撞检测
// 在endSelection方法中添加
const selectedElements = []
const elements = document.querySelectorAll('.selectable-item') // 需选中的元素类名
elements.forEach(el => {
const rect = el.getBoundingClientRect()
if (
rect.right > Math.min(this.startX, this.currentX) &&
rect.left < Math.max(this.startX, this.currentX) &&
rect.bottom > Math.min(this.startY, this.currentY) &&
rect.top < Math.max(this.startY, this.currentY)
) {
selectedElements.push(el)
el.classList.add('selected') // 添加选中样式
}
})
性能优化
- 使用requestAnimationFrame优化拖动渲染
- 添加防抖处理频繁的mousemove事件
- 对于大量可选元素采用虚拟滚动技术
样式建议
.selection-area {
position: relative;
width: 100%;
height: 100%;
user-select: none;
}
.selectable-item {
transition: all 0.2s;
}
.selectable-item.selected {
background-color: rgba(100, 180, 255, 0.2);
border: 1px solid #64b4ff;
}
注意事项
- 需要考虑页面滚动时的坐标计算
- 移动端需添加touch事件支持
- 多层级元素需处理z-index和事件冒泡
- 对于复杂场景建议使用第三方库如interact.js







