vue实现table封装
封装 Vue Table 组件的基本思路
封装一个可复用的 Vue Table 组件需要考虑灵活性、可配置性和易用性。核心是通过 props 接收数据和配置,通过插槽(slots)提供自定义内容的能力。
基础 Table 封装示例
创建一个基础的表格组件,支持动态列和数据渲染:
<template>
<table class="base-table">
<thead>
<tr>
<th v-for="column in columns" :key="column.prop">
{{ column.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in data" :key="index">
<td v-for="column in columns" :key="column.prop">
{{ row[column.prop] }}
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: 'BaseTable',
props: {
columns: {
type: Array,
required: true,
default: () => []
},
data: {
type: Array,
required: true,
default: () => []
}
}
}
</script>
<style scoped>
.base-table {
width: 100%;
border-collapse: collapse;
}
.base-table th, .base-table td {
border: 1px solid #ddd;
padding: 8px;
}
.base-table th {
background-color: #f2f2f2;
}
</style>
添加自定义列内容支持
通过作用域插槽允许自定义单元格内容:

<template>
<table class="base-table">
<thead>
<tr>
<th v-for="column in columns" :key="column.prop">
{{ column.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in data" :key="index">
<td v-for="column in columns" :key="column.prop">
<slot
v-if="column.slot"
:name="column.prop"
:row="row"
:index="index"
></slot>
<template v-else>
{{ row[column.prop] }}
</template>
</td>
</tr>
</tbody>
</table>
</template>
添加排序功能
扩展组件支持列排序:
<script>
export default {
name: 'SortableTable',
props: {
columns: {
type: Array,
required: true,
default: () => []
},
data: {
type: Array,
required: true,
default: () => []
}
},
data() {
return {
sortKey: '',
sortOrder: 'asc'
}
},
computed: {
sortedData() {
if (!this.sortKey) return this.data
return [...this.data].sort((a, b) => {
const valA = a[this.sortKey]
const valB = b[this.sortKey]
if (this.sortOrder === 'asc') {
return valA > valB ? 1 : -1
} else {
return valA < valB ? 1 : -1
}
})
}
},
methods: {
handleSort(prop) {
if (this.sortKey === prop) {
this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
} else {
this.sortKey = prop
this.sortOrder = 'asc'
}
}
}
}
</script>
添加分页功能
扩展组件支持分页:

<template>
<div>
<table class="base-table">
<!-- 表头 -->
<thead>
<tr>
<th v-for="column in columns" :key="column.prop">
{{ column.label }}
</th>
</tr>
</thead>
<!-- 表体 -->
<tbody>
<tr v-for="(row, index) in paginatedData" :key="index">
<td v-for="column in columns" :key="column.prop">
<slot
v-if="column.slot"
:name="column.prop"
:row="row"
:index="index"
></slot>
<template v-else>
{{ row[column.prop] }}
</template>
</td>
</tr>
</tbody>
</table>
<div class="pagination">
<button @click="prevPage" :disabled="currentPage === 1">上一页</button>
<span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
<button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
</div>
</div>
</template>
<script>
export default {
props: {
columns: Array,
data: Array,
pageSize: {
type: Number,
default: 10
}
},
data() {
return {
currentPage: 1
}
},
computed: {
totalPages() {
return Math.ceil(this.data.length / this.pageSize)
},
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize
const end = start + this.pageSize
return this.data.slice(start, end)
}
},
methods: {
nextPage() {
if (this.currentPage < this.totalPages) {
this.currentPage++
}
},
prevPage() {
if (this.currentPage > 1) {
this.currentPage--
}
}
}
}
</script>
高级封装建议
对于更复杂的表格需求,可以考虑以下增强功能:
- 添加行选择功能,支持单选和多选
- 实现列固定和表头固定
- 支持表格编辑功能
- 添加树形表格展示
- 实现虚拟滚动提升大数据量性能
- 支持列拖拽排序
- 添加表格导出功能
使用第三方库
对于复杂表格需求,可以考虑基于以下流行库进行二次封装:
- Element UI 的 Table 组件
- Ant Design Vue 的 Table 组件
- VxeTable 专业表格解决方案
- AG Grid 企业级表格组件
这些库已经提供了丰富的功能,可以通过二次封装来满足特定业务需求。






