vue实现列全选框
实现全选框的基本逻辑
在Vue中实现表格列的全选框功能,需要结合v-model和计算属性来管理选中状态。全选框的状态应反映当前页所有行的选中情况,同时点击全选框应能切换所有行的选中状态。
<template>
<table>
<thead>
<tr>
<th>
<input
type="checkbox"
v-model="allSelected"
@change="toggleAll"
>
</th>
<!-- 其他表头列 -->
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td>
<input
type="checkbox"
v-model="selectedItems"
:value="item.id"
>
</td>
<!-- 其他数据列 -->
</tr>
</tbody>
</table>
</template>
核心代码实现
<script>
export default {
data() {
return {
items: [...], // 表格数据
selectedItems: [] // 存储选中项的ID
}
},
computed: {
allSelected: {
get() {
return this.selectedItems.length === this.items.length &&
this.items.length > 0
},
set(value) {
this.selectedItems = value ? this.items.map(item => item.id) : []
}
}
},
methods: {
toggleAll() {
this.allSelected = !this.allSelected
}
}
}
</script>
处理分页场景
当表格存在分页时,需要区分"当前页全选"和"全部数据全选"两种模式:
computed: {
currentPageAllSelected() {
const currentPageIds = this.paginatedItems.map(item => item.id)
return currentPageIds.every(id => this.selectedItems.includes(id))
}
},
methods: {
toggleCurrentPage() {
const currentPageIds = this.paginatedItems.map(item => item.id)
const allSelected = currentPageIds.every(id =>
this.selectedItems.includes(id)
)
if (allSelected) {
this.selectedItems = this.selectedItems.filter(
id => !currentPageIds.includes(id)
)
} else {
const newSelected = [...new Set([
...this.selectedItems,
...currentPageIds
])]
this.selectedItems = newSelected
}
}
}
样式优化建议
为提升用户体验,可以添加以下CSS样式:
<style scoped>
/* 使复选框对齐 */
th, td {
text-align: center;
}
/* 悬浮效果 */
tr:hover {
background-color: #f5f5f5;
}
/* 选中行高亮 */
tr.selected {
background-color: #e6f7ff;
}
</style>
性能优化方案
对于大数据量场景,建议使用以下优化手段:
// 使用Set代替数组提高查找效率
computed: {
selectedItemsSet() {
return new Set(this.selectedItems)
},
allSelected() {
return this.items.length > 0 &&
this.items.every(item => this.selectedItemsSet.has(item.id))
}
}
完整组件示例
<template>
<div>
<div class="controls">
<span>已选择 {{ selectedItems.length }} 项</span>
<button
v-if="selectedItems.length"
@click="selectedItems = []"
>
取消选择
</button>
</div>
<table>
<thead>
<tr>
<th>
<input
type="checkbox"
:indeterminate="indeterminate"
v-model="allSelected"
>
</th>
<!-- 其他列 -->
</tr>
</thead>
<tbody>
<tr
v-for="item in items"
:key="item.id"
:class="{ selected: isSelected(item.id) }"
>
<td>
<input
type="checkbox"
v-model="selectedItems"
:value="item.id"
>
</td>
<!-- 其他列 -->
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['items'],
data() {
return {
selectedItems: []
}
},
computed: {
allSelected: {
get() {
return this.selectedItems.length === this.items.length &&
this.items.length > 0
},
set(value) {
this.selectedItems = value ? this.items.map(item => item.id) : []
}
},
indeterminate() {
return this.selectedItems.length > 0 &&
this.selectedItems.length < this.items.length
}
},
methods: {
isSelected(id) {
return this.selectedItems.includes(id)
}
}
}
</script>






