当前位置: 首页 > news >正文

使用Vue + Element Plus实现可多行编辑的分页表格

需求背景:
        在现代前端开发中,表格作为数据展示和交互的重要组件,在各类管理系统、数据平台中有着广泛的应用。随着用户对数据操作便捷性要求的不断提高,具备灵活编辑功能的表格成为了开发中的常见需求。特别是在需求处理大量数据时,不仅要实现数据的分页展示,还要支持对数据的实时编辑,并且要保证在复杂操作场景下的数据状态管理。
        本次demo是人员信息管理的场景。
        在该场景下,需要一个能够展示人员基本信息(包括ID、姓名、年龄、职业、爱好等)的表格,同时要求具备强大的编辑功能。具体来说,需要在表格中实现编辑按钮,点击后能对该行的职业和爱好进行修改,其中职业通过文本框编辑,爱好通过下拉框选择。此外,考虑到数据量较大的情况,表格需要支持分页展示,每页展示5条数据为例。更为关键的是,要实现多行数据同时编辑的功能,并且在切换分页时,能将数据恢复到初始化状态,确保用户操作的一致性和数据展示的准确性,提升系统的易用性和交互体验。
代码展示:

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElTable, ElTableColumn, ElPagination, ElButton, ElInput, ElSelect, ElOption } from 'element-plus'interface TableItem {id: numbername: stringage: numberprofession: stringhobby: stringisEditing: booleanoriginalData?: {profession: stringhobby: string}
}const hobbies = ['读书', '运动', '音乐', '旅游', '游戏']const tableData = ref<TableItem[]>([{ id: 1, name: '张三', age: 25, profession: '工程师', hobby: '读书', isEditing: false },{ id: 2, name: '李四', age: 28, profession: '设计师', hobby: '运动', isEditing: false },{ id: 3, name: '王五', age: 30, profession: '教师', hobby: '音乐', isEditing: false },{ id: 4, name: '赵六', age: 22, profession: '学生', hobby: '游戏', isEditing: false },{ id: 5, name: '钱七', age: 35, profession: '医生', hobby: '旅游', isEditing: false },{ id: 6, name: '孙八', age: 27, profession: '销售', hobby: '运动', isEditing: false },{ id: 7, name: '周九', age: 32, profession: '会计', hobby: '读书', isEditing: false },{ id: 8, name: '吴十', age: 29, profession: '律师', hobby: '音乐', isEditing: false },{ id: 9, name: '郑十一', age: 31, profession: '记者', hobby: '旅游', isEditing: false },{ id: 10, name: '王十二', age: 26, profession: '作家', hobby: '游戏', isEditing: false },
])const currentPage = ref(1)
const pageSize = ref(5)const paginatedData = computed(() => {const start = (currentPage.value - 1) * pageSize.valueconst end = start + pageSize.valuereturn tableData.value.slice(start, end)
})const handleEdit = (row: TableItem) => {row.isEditing = truerow.originalData = {profession: row.profession,hobby: row.hobby}
}const handleSave = (row: TableItem) => {row.isEditing = false;// 实际开发中,调用接口,是否使用delete row.originalData视情况而定delete row.originalData
}const handleCancel = (row: TableItem) => {
// 取消操作时,务必还原之前的数据if (row.originalData) {row.profession = row.originalData.professionrow.hobby = row.originalData.hobby}row.isEditing = false// 实际开发中,调用接口,是否使用delete row.originalData视情况而定delete row.originalData
}const handlePageChange = (page: number) => {currentPage.value = page;// Reset editing state for all rows,仅为静态数据展示使用;实际开发调用接口,无需单独处理tableData.value.forEach(row => {if (row.isEditing) {handleCancel(row)}})
}
</script><template><div class="table-container"><el-table :data="paginatedData" style="width: 100%"><el-table-column prop="id" label="ID" width="80" /><el-table-column prop="name" label="姓名" width="120" /><el-table-column prop="age" label="年龄" width="80" /><el-table-column label="职业" width="180"><template #default="{ row }"><el-inputv-if="row.isEditing"v-model="row.profession"size="small"/><span v-else>{{ row.profession }}</span></template></el-table-column><el-table-column label="爱好" width="180"><template #default="{ row }"><el-selectv-if="row.isEditing"v-model="row.hobby"size="small"style="width: 100%"><el-optionv-for="hobby in hobbies":key="hobby":label="hobby":value="hobby"/></el-select><span v-else>{{ row.hobby }}</span></template></el-table-column><el-table-column label="操作" width="180"><template #default="{ row }"><template v-if="row.isEditing"><el-button type="success" size="small" @click="handleSave(row)">保存</el-button><el-button type="info" size="small" @click="handleCancel(row)">取消</el-button></template><el-button v-else type="primary" size="small" @click="handleEdit(row)">编辑</el-button></template></el-table-column></el-table><div class="pagination"><el-paginationv-model:current-page="currentPage":page-size="pageSize":total="tableData.length"layout="prev, pager, next"@current-change="handlePageChange"/></div></div>
</template><style scoped>
.table-container {width: 100%;max-width: 1000px;margin: 0 auto;
}.pagination {margin-top: 20px;display: flex;justify-content: center;
}.el-button {margin-right: 8px;
}.el-button:last-child {margin-right: 0;
}
</style>

上面代码仅为静态数据参考,在实际开发中,我实际的开发逻辑为下面的 条

  1. 初始化调用列表数据,通过map方法为每一条数据增加一个isEdit属性,值为false;增加一个originalData记录需要变更的字段或者如上所示,在interface中声明一个originalData可选属性,在编辑数据时,再进行复制
  2. 点击编辑,将isEdit值改为true
  3. 保存操作,给接口传参,将修改的值进行本地赋值,如爱好下拉框选项卡,实际开发中显示的都是Desc字段,需要进行处理。保存后,不调用列表接口,否则,就无法实现多行编辑
  4. 取消操作,一定要把原始值进行赋值,否则点击编辑时,显示的数据为编辑后未保存的值。
  5. 分页切换,展示为初始化状态,只需要正常调用接口即可。

实现效果如下图所示:
在这里插入图片描述
希望上述内容对你实现类似功能有所帮助。如果你有更优的实现方法或遇到了其他问题,欢迎在评论区留言分享,我们可以一起探讨优化方案。

相关文章:

  • APL Photonics封面成果:KAUST用五边形激光腔刷新物理随机数生成极限——800Gb/s!
  • Ovito建模并正交化方法
  • webstrorm 提示(This file does not belong to the project)此文件不属于该项目
  • MVCC原理解析
  • 扩展摩尔投票法:找出出现次数超过 n/3 的元素
  • DAY 36神经网络加速器easy
  • 网络协议之办公室网络是怎样的?
  • 实验设计与分析(第6版,Montgomery)第3章单因子实验:方差分析3.11思考题3.7 R语言解题
  • 卸载 Office PLUS
  • ZYNQ-PS与PL端BRAM数据交互
  • PortSwigger-03-点击劫持
  • 链路追踪神器zipkin安装详细教程教程
  • Redis击穿,穿透和雪崩详解以及解决方案
  • Polar编译码(SCL译码)和LDPC编译码(BP译码)的matlab性能仿真,并对比香浓限
  • BEVDepth- Acquisition of Reliable Depth for Multi-view 3D Object Detection
  • 数据库管理与高可用-MySQL数据库操作
  • C# Datatable筛选过滤各方式详解
  • 智变与重构:AI 赋能基础教育教学的范式转型研究报告
  • jmeter对数据库进行单独压测
  • 黑马程序员C++核心编程笔记--3 函数高级
  • 秦皇岛黄金海岸收费吗/青岛百度关键词优化
  • 萍乡建站公司/市场推广方案和思路
  • 网站群系统/360地图怎么添加商户
  • 黄页88网站关键词怎么做/公众号如何推广
  • 网站建设和管理专业/黄页网络的推广
  • 苏州360推广网站建设/线上宣传渠道