文章介绍了如何在Vue3和ElementPlus中封装一个包含分页功能的通用列表表格组件,组件通过props接收表格数据、列配置、总条数、加载状态和分页配置,并通过events处理分页和刷新事件,此外,还提供了自定义列内容和操作按钮的功能,感兴趣的朋友跟随小编一起看看吧
目录
1. 组件设计2. 封装代码3. 使用示例在前端开发中,封装组件是必不可少的。今天就来封装一个通用的列表表格组件,包含分页功能,可以提高代码的复用性和可维护性。
1. 组件设计
Props:
tableData:表格数据。columns:表格列配置。total:总条数。loading:加载状态。pagination:分页配置(当前页、每页条数)。Events:
update:pagination:分页变化时触发。refresh:刷新数据时触发。Slots:
自定义列内容。自定义操作按钮。
2. 封装代码
TableWithPagination.vue
<template> <div class="table-with-pagination"> <!-- 表格 --> <el-table :data="tableData" border stripe v-loading="loading" style="width: 100%" > <!-- 动态列 --> <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label" :width="column.width" :align="column.align || 'center'" > <!-- 自定义列内容 --> <template #default="scope" v-if="column.slot"> <slot :name="column.slot" :row="scope.row"></slot> </template> </el-table-column> <!-- 操作列 --> <el-table-column v-if="$slots.actions" label="操作" align="center" :width="actionsWidth" > <template #default="scope"> <slot name="actions" :row="scope.row"></slot> </template> </el-table-column> </el-table> <!-- 分页 --> <el-pagination class="pagination" background layout="total, sizes, prev, pager, next, jumper" :total="total" :page-size="pagination.pageSize" :current-page="pagination.pageNo" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div></template><script setup>import { ref, watch } from 'vue';const props = defineProps({ tableData: { type: Array, default: () => [], }, columns: { type: Array, default: () => [], }, total: { type: Number, default: 0, }, loading: { type: Boolean, default: false, }, pagination: { type: Object, default: () => ({ pageNo: 1, pageSize: 10, }), }, actionsWidth: { type: String, default: '180', },});const emit = defineEmits(['update:pagination', 'refresh']);// 分页大小变化const handleSizeChange = (pageSize) => { emit('update:pagination', { ...props.pagination, pageSize }); emit('refresh');};// 当前页变化const handleCurrentChange = (pageNo) => { emit('update:pagination', { ...props.pagination, pageNo }); emit('refresh');};</script><style scoped>.table-with-pagination { margin-top: 20px;}.pagination { margin-top: 20px; text-align: right;}</style>
3. 使用示例
<template> <div> <!-- 搜索栏 --> <el-form :inline="true" :model="queryParams"> <el-form-item label="任务名称"> <el-input v-model="queryParams.taskName" placeholder="请输入任务名称" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleSearch">搜索</el-button> </el-form-item> </el-form> <!-- 表格组件 --> <TableWithPagination :table-data="tableData" :columns="columns" :total="total" :loading="loading" :pagination="pagination" @update:pagination="handlePaginationChange" @refresh="fetchData" > <!-- 自定义列 --> <template #status="{ row }"> <el-tag :type="row.status === 1 ? 'success' : 'danger'"> { { row.status === 1 ? '启用' : '禁用' }} </el-tag> </template> <!-- 操作列 --> <template #actions="{ row }"> <el-button type="primary" size="small" @click="handleEdit(row)"> 编辑 </el-button> <el-button type="danger" size="small" @click="handleDelete(row)"> 删除 </el-button> </template> </TableWithPagination> </div></template><script setup>import { ref, onMounted } from 'vue';import TableWithPagination from './components/TableWithPagination.vue';import { fetchTaskList } from '@/api/task'; // 假设有一个获取任务列表的 API// 表格列配置const columns = [ { prop: 'taskName', label: '任务名称' }, { prop: 'taskType', label: '任务类型' }, { prop: 'status', label: '状态', slot: 'status' }, // 使用自定义列];// 表格数据const tableData = ref([]);const total = ref(0);const loading = ref(false);// 查询参数const queryParams = ref({ taskName: '',});// 分页参数const pagination = ref({ pageNo: 1, pageSize: 10,});// 获取数据const fetchData = async () => { try { loading.value = true; const res = await fetchTaskList({ ...queryParams.value, ...pagination.value, }); tableData.value = res.data.list; total.value = res.data.total; } catch (error) { console.error('获取数据失败:', error); } finally { loading.value = false; }};// 分页变化const handlePaginationChange = (newPagination) => { pagination.value = newPagination; fetchData();};// 搜索const handleSearch = () => { pagination.value.pageNo = 1; // 重置页码 fetchData();};// 编辑const handleEdit = (row) => { console.log('编辑:', row);};// 删除const handleDelete = (row) => { console.log('删除:', row);};// 初始化加载数据onMounted(() => { fetchData();});</script>
父组件中使用 TableWithPagination