7.4Element Plus 分页与表格组件
el-pagination el-table
这两个组件是后台管理系统中最常用的数据展示与交互组合,通常配合使用实现 分页加载、排序、筛选、操作 等功能。
一、分页组件 el-pagination
用于控制大量数据的分页展示。
✅ 基本结构
<el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":total="total":page-sizes="[10, 20, 50, 100]"layout="total, sizes, prev, pager, next, jumper"background
/>
🔧 核心属性(Props)
属性 | 类型 | 说明 | 默认值 |
---|---|---|---|
v-model:current-page | number | 当前页码(双向绑定) | 1 |
v-model:page-size | number | 每页条数(双向绑定) | 10 |
total | number | 总数据条数 | 0 |
page-sizes | number[] | 每页显示条数选择器选项 | [10, 20, 30, 40, 50, 100] |
layout | string | 组件布局,用逗号分隔 | 'prev, pager, next' |
background | boolean | 是否为按钮添加背景色 | false |
disabled | boolean | 是否禁用分页 | false |
small | boolean | 是否使用小型分页 | false |
layout
可选值:
total
: 总条数sizes
: 每页条数选择器prev
: 上一页pager
: 页码列表next
: 下一页jumper
: 跳转输入框->
: 分隔符(将后续元素推到右侧)
📢 事件(Events)
事件 | 说明 | 回调参数 |
---|---|---|
@size-change | 每页条数改变时触发 | 改变后的 pageSize |
@current-change | 当前页改变时触发 | 改变后的 currentPage |
@prev-click | 点击上一页时触发 | - |
@next-click | 点击下一页时触发 | - |
⚠️ 注意:使用
v-model
后,通常只需监听@size-change
和@current-change
来重新请求数据。
二、表格组件 el-table
用于展示结构化数据。
✅ 基本结构
<el-table :data="tableData" style="width: 100%"><el-table-column prop="name" label="姓名" /><el-table-column prop="age" label="年龄" />
</el-table>
🔧 表格核心属性(el-table
Props)
属性 | 类型 | 说明 |
---|---|---|
data | array | 显示的数据源 |
stripe | boolean | 是否显示斑马纹 |
border | boolean | 是否显示纵向边框 |
fit | boolean | 列宽是否自撑开 |
height | string/number | 固定高度,超出出现滚动条 |
max-height | string/number | 最大高度 |
highlight-current-row | boolean | 高亮当前行 |
empty-text | string | 数据为空时显示文本 |
v-loading | boolean | 是否显示加载中 |
🔧 列定义 el-table-column
属性
属性 | 类型 | 说明 |
---|---|---|
type | string | 列类型:selection , index , expand |
label | string | 列标题 |
prop | string | 对应字段名 |
width / min-width | string/number | 列宽 |
fixed | string/boolean | 固定列:left , right |
sortable | boolean/string | 是否可排序,custom 为自定义 |
formatter | Function | 格式化内容函数 |
show-overflow-tooltip | boolean | 内容过长显示 tooltip |
align / header-align | string | 对齐方式:left , center , right |
🧩 高级功能
1. 复选框列
<el-table-column type="selection" width="55" />
2. 序号列
<el-table-column type="index" label="序号" width="80" />
3. 可展开行
<el-table-column type="expand"><template #default="props"><p>详情:{{ props.row.detail }}</p></template>
</el-table-column>
4. 自定义列模板
<el-table-column label="操作" width="180"><template #default="{ row }"><el-button size="small" @click="edit(row)">编辑</el-button><el-button size="small" type="danger">删除</el-button></template>
</el-table-column>
5. 排序
<el-table-column prop="age" label="年龄" sortable />
<!-- 或自定义排序 -->
<el-table-column prop="age" label="年龄" sortable="custom" @sort-change="handleSort" />
6. 筛选
<el-table-columnprop="tag"label="标签":filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]":filter-method="filterTag"
/>
function filterTag(value, row) {return row.tag === value
}
三、实战案例(完整)
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'// 响应式数据
const tableData = ref([])
const total = ref(0)
const loading = ref(false)// 分页
const currentPage = ref(1)
const pageSize = ref(10)// 搜索与排序
const searchKey = ref('')
const sortState = reactive({ prop: '', order: '' })// 模拟数据获取
const fetchData = () => {loading.value = truesetTimeout(() => {const allData = Array.from({ length: 100 }, (_, i) => ({id: i + 1,name: `用户${i + 1}`,age: 18 + (i % 50),address: `地址 ${i + 1}`}))// 搜索let filtered = allData.filter(item => item.name.includes(searchKey.value))// 排序if (sortState.prop && sortState.order) {filtered.sort((a, b) => {const diff = a[sortState.prop] - b[sortState.prop]return sortState.order === 'descending' ? -diff : diff})}// 分页const start = (currentPage.value - 1) * pageSize.valueconst end = start + pageSize.valuetableData.value = filtered.slice(start, end)total.value = filtered.lengthloading.value = false}, 500)
}// 事件
const handleSearch = () => {currentPage.value = 1fetchData()
}const handleSortChange = ({ prop, order }) => {sortState.prop = propsortState.order = ordercurrentPage.value = 1fetchData()
}const handleEdit = (row) => ElMessage.info(`编辑:${row.name}`)
const handleDelete = (row) => {ElMessageBox.confirm(`删除 ${row.name}?`, '确认', { type: 'warning' }).then(() => ElMessage.success('删除成功')).catch(() => ElMessage.info('取消'))
}onMounted(() => fetchData())
</script><template><div class="p-4"><div class="flex justify-between mb-4"><h3 class="text-lg font-medium">用户列表</h3><el-input v-model="searchKey" placeholder="搜索姓名" @input="handleSearch" style="width: 240px" /></div><el-table :data="tableData" stripe border v-loading="loading" @sort-change="handleSortChange"><el-table-column type="index" label="序号" width="80" /><el-table-column prop="name" label="姓名" sortable /><el-table-column prop="age" label="年龄" sortable width="100" /><el-table-column prop="address" label="地址" show-overflow-tooltip /><el-table-column label="操作" width="160"><template #default="{ row }"><el-button size="small" @click="handleEdit(row)">编辑</el-button><el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button></template></el-table-column></el-table><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":total="total"layout="total, sizes, prev, pager, next, jumper"background@size-change="fetchData"@current-change="fetchData"class="mt-4 justify-end"/></div>
</template>