vue实现框选
Vue 框选功能实现
框选功能通常用于通过鼠标拖动选择多个元素,常见于表格、图形或列表。以下是实现步骤:
1. 基础结构 在 Vue 模板中添加框选区域和待选元素:
<template>
<div
class="selection-area"
@mousedown="startSelection"
@mousemove="updateSelection"
@mouseup="endSelection"
>
<div
v-for="item in items"
:key="item.id"
class="selectable-item"
:class="{ selected: item.selected }"
>
{{ item.name }}
</div>
<div
v-if="isSelecting"
class="selection-box"
:style="boxStyle"
/>
</div>
</template>
2. 数据与样式 定义必要的数据和基础样式:
data() {
return {
items: [...], // 待选元素数组
startPos: { x: 0, y: 0 },
currentPos: { x: 0, y: 0 },
isSelecting: false
}
},
computed: {
boxStyle() {
return {
left: Math.min(this.startPos.x, this.currentPos.x) + 'px',
top: Math.min(this.startPos.y, this.currentPos.y) + 'px',
width: Math.abs(this.currentPos.x - this.startPos.x) + 'px',
height: Math.abs(this.currentPos.y - this.startPos.y) + 'px'
}
}
}
.selection-area {
position: relative;
width: 100%;
height: 500px;
}
.selectable-item {
position: absolute;
border: 1px solid #ccc;
}
.selection-box {
position: absolute;
background: rgba(0, 120, 255, 0.1);
border: 1px dashed #0078ff;
}
.selected {
background-color: #e0f7fa;
}
3. 事件处理 实现鼠标事件逻辑:
methods: {
startSelection(e) {
this.isSelecting = true
this.startPos = { x: e.clientX, y: e.clientY }
this.currentPos = { ...this.startPos }
},
updateSelection(e) {
if (!this.isSelecting) return
this.currentPos = { x: e.clientX, y: e.clientY }
this.checkSelection()
},
endSelection() {
this.isSelecting = false
}
}
4. 碰撞检测 添加元素选择判断逻辑:
checkSelection() {
const selectionRect = {
left: Math.min(this.startPos.x, this.currentPos.x),
right: Math.max(this.startPos.x, this.currentPos.x),
top: Math.min(this.startPos.y, this.currentPos.y),
bottom: Math.max(this.startPos.y, this.currentPos.y)
}
this.items.forEach(item => {
const el = document.querySelector(`[data-id="${item.id}"]`)
if (!el) return
const rect = el.getBoundingClientRect()
const isSelected =
rect.right > selectionRect.left &&
rect.left < selectionRect.right &&
rect.bottom > selectionRect.top &&
rect.top < selectionRect.bottom
this.$set(item, 'selected', isSelected)
})
}
5. 性能优化 对于大量元素可添加防抖和虚拟滚动:
import { debounce } from 'lodash'
export default {
methods: {
updateSelection: debounce(function(e) {
// 原有逻辑
}, 16)
}
}
6. 扩展功能 支持快捷键多选:

mounted() {
window.addEventListener('keydown', (e) => {
this.ctrlPressed = e.ctrlKey || e.metaKey
})
window.addEventListener('keyup', () => {
this.ctrlPressed = false
})
}
// 修改 checkSelection 方法
if (isSelected && !this.ctrlPressed) {
this.items.forEach(i => i.selected = false)
}
以上实现可根据具体需求调整选择策略和样式表现。对于复杂场景,可以考虑使用第三方库如 interact.js 或 selecto.js。






