vue实现简单表格组件
实现基础表格结构
使用Vue的模板语法构建表格基础结构,包含表头和表体两部分。表头通过v-for动态渲染,表体使用双重v-for循环渲染行列数据。
<template>
<table class="vue-table">
<thead>
<tr>
<th v-for="(header, index) in headers" :key="index">
{{ header.text }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, rowIndex) in items" :key="rowIndex">
<td v-for="(header, colIndex) in headers" :key="colIndex">
{{ item[header.value] }}
</td>
</tr>
</tbody>
</table>
</template>
定义组件props
通过props接收外部传入的表格数据和列配置。headers定义列显示文本和对应字段,items包含实际行数据。
<script>
export default {
props: {
headers: {
type: Array,
required: true,
default: () => []
},
items: {
type: Array,
required: true,
default: () => []
}
}
}
</script>
添加基础样式
为表格添加基础CSS样式,增强可视化效果。包括边框、间距和悬停效果等基础样式设置。
<style scoped>
.vue-table {
width: 100%;
border-collapse: collapse;
}
.vue-table th, .vue-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.vue-table th {
background-color: #f2f2f2;
}
.vue-table tr:hover {
background-color: #f5f5f5;
}
</style>
实现排序功能
扩展组件功能,添加列排序能力。通过点击表头触发排序,使用计算属性处理排序逻辑。
<script>
export default {
data() {
return {
sortKey: '',
sortOrder: 'asc'
}
},
computed: {
sortedItems() {
if (!this.sortKey) return this.items
return [...this.items].sort((a, b) => {
const valA = a[this.sortKey]
const valB = b[this.sortKey]
return this.sortOrder === 'asc'
? valA > valB ? 1 : -1
: valA < valB ? 1 : -1
})
}
},
methods: {
sortBy(key) {
this.sortOrder = this.sortKey === key
? this.sortOrder === 'asc' ? 'desc' : 'asc'
: 'asc'
this.sortKey = key
}
}
}
</script>
更新模板部分,添加排序事件和指示图标:

<th v-for="(header, index) in headers"
:key="index"
@click="sortBy(header.value)">
{{ header.text }}
<span v-if="sortKey === header.value">
{{ sortOrder === 'asc' ? '↑' : '↓' }}
</span>
</th>
添加分页功能
通过计算属性和方法实现客户端分页,控制每页显示的数据量。
<script>
export default {
props: {
pageSize: {
type: Number,
default: 10
}
},
data() {
return {
currentPage: 1
}
},
computed: {
paginatedItems() {
const start = (this.currentPage - 1) * this.pageSize
return this.sortedItems.slice(start, start + this.pageSize)
},
totalPages() {
return Math.ceil(this.sortedItems.length / this.pageSize)
}
},
methods: {
prevPage() {
if (this.currentPage > 1) this.currentPage--
},
nextPage() {
if (this.currentPage < this.totalPages) this.currentPage++
}
}
}
</script>
添加分页控制UI:
<div class="pagination">
<button @click="prevPage" :disabled="currentPage === 1">Previous</button>
<span>Page {{ currentPage }} of {{ totalPages }}</span>
<button @click="nextPage" :disabled="currentPage === totalPages">Next</button>
</div>
添加行选择功能
实现行选择功能,支持单选和多选模式。通过数据绑定管理选中状态。

<script>
export default {
props: {
selectable: {
type: Boolean,
default: false
},
multiSelect: {
type: Boolean,
default: false
}
},
data() {
return {
selectedRows: []
}
},
methods: {
toggleRowSelection(row) {
if (this.multiSelect) {
const index = this.selectedRows.indexOf(row)
index === -1
? this.selectedRows.push(row)
: this.selectedRows.splice(index, 1)
} else {
this.selectedRows = [row]
}
}
}
}
</script>
更新模板添加选择列和行点击事件:
<th v-if="selectable"></th>
<td v-if="selectable">
<input type="checkbox"
:checked="selectedRows.includes(item)"
@change="toggleRowSelection(item)">
</td>
<tr @click="selectable && toggleRowSelection(item)">
实现单元格自定义渲染
通过作用域插槽支持单元格内容自定义渲染,提供更大的灵活性。
<td v-for="(header, colIndex) in headers" :key="colIndex">
<slot :name="`cell-${header.value}`" :item="item">
{{ item[header.value] }}
</slot>
</td>
使用示例:
<vue-table :headers="headers" :items="data">
<template #cell-action="{ item }">
<button @click="handleAction(item)">Edit</button>
</template>
</vue-table>






