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

Vue3+Vite+TypeScript项目中跨页多选表格的实现与应用

在企业级管理系统、数据中台等复杂前端项目中,表格作为数据展示与交互的核心组件,常面临数据量庞大需分页展示的场景。例如在管理系统中,需要在多页数据中批量勾选目标条目(如批量导出、批量删除)。

基于此,实现一个支持跨页选择的复选框表格成为提升用户体验的关键需求。该功能需要解决数据分页加载时选中状态的持久化维护、不同页面间勾选逻辑的一致性,以及结合TypeScript类型安全特性确保数据操作的可靠性,同时兼顾组件性能与可维护性,为复杂数据交互场景提供高效的解决方案。

交互演示与核心功能说明:

  1. 空状态展示:页面初始加载时呈现所有未被选中的数据
  2. 跨页选中功能演示:
    在不同分页间勾选数据行,表格自动维护选中状态
    切换页码时保留已选数据,支持连续跨页批量操作
  3. 数据获取与处理
    点击“获取选中数据”按钮,实时提取选中项ID集合
    支持两种数据获取模式:仅ID数组或完整数据对象
    在控制台输出选中结果(实际项目中可用于批量提交、导出等操作)
  4. 编辑场景模拟
    点击“渲染数据”按钮,模拟编辑页回显已选数据
    自动选中已被选择过的数据

第一种:采用原生html实现
代码如下:

<script setup lang="ts">
import { ref, computed } from 'vue'const tableData = ref([{id: 1,name: 'aaa',age: 18},{id: 2,name: 'bbb',age: 17},{id: 3,name: 'ccc',age: 16},{id: 4,name: 'ddd',age: 15},{id: 5,name: 'eeee',age: 14},{id: 6,name: 'fff',age: 19},{id: 7,name: 'ggg',age: 20},{id: 8,name: 'hhh',age: 21},{id: 9,name: 'iii',age: 22},{id: 10,name: 'jjj',age: 23},
])const pageSize = 5
const currentPage = ref(1)const totalPages = computed(() => Math.ceil(tableData.value.length / pageSize))const paginatedData = computed(() => {const start = (currentPage.value - 1) * pageSizeconst end = start + pageSizereturn tableData.value.slice(start, end)
})const nextPage = () => {if (currentPage.value < totalPages.value) {currentPage.value++}
}const prevPage = () => {if (currentPage.value > 1) {currentPage.value--}
}const selectedItems = ref<number[]>([]) // Initialize with IDs 2 and 8const toggleSelection = (id: number) => {const index = selectedItems.value.indexOf(id)if (index === -1) {selectedItems.value.push(id)} else {selectedItems.value.splice(index, 1)}
}const getSelectedData = () => {// 获取单条数据的idconsole.log('selectData', selectedItems.value)// 获取单条数据const selectedData = tableData.value.filter(item => selectedItems.value.includes(item.id))console.log(JSON.stringify(selectedData, null, 2))
}const setSelectedData = () =>{selectedItems.value = [2,8]
}</script><template><div><table class="border"><tr><th></th><th>名字</th><th>年龄</th></tr><tr v-for="item in paginatedData" :key="item.id"><td><input type="checkbox" :checked="selectedItems.includes(item.id)"@change="toggleSelection(item.id)"/></td><td>{{item.name}}</td><td>{{item.age}}</td></tr></table><div class="pagination"><button @click="prevPage" :disabled="currentPage === 1">上一页</button><span>{{ currentPage }} / {{ totalPages }}</span><button @click="nextPage" :disabled="currentPage === totalPages">下一页</button></div><div class="selected-info">已选择: {{ selectedItems.length }}<button class="get-data-btn" @click="getSelectedData">获取选中的数据</button><button class="get-data-btn" @click="setSelectedData">渲染数据</button></div></div>
</template><style scoped>
.border {width: 400px;border: 1px solid lightyellow;margin-bottom: 1rem;
}.pagination {display: flex;gap: 1rem;align-items: center;justify-content: center;margin-bottom: 1rem;
}.selected-info {text-align: center;color: #646cff;
}button {padding: 0.5rem 1rem;
}button:disabled {opacity: 0.5;cursor: not-allowed;
}.get-data-btn {margin-left: 1rem;background-color: #42b883;color: white;
}.get-data-btn:hover {border-color: #42b883;
}
</style>

实现效果如下:
在这里插入图片描述
第二种:采用element-plus实现
代码如下:

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElTable, ElTableColumn, ElPagination, ElButton } from 'element-plus'const tableData = ref([{ id: 1, name: 'aaa', age: 18 },{ id: 2, name: 'bbb', age: 17 },{ id: 3, name: 'ccc', age: 16 },{ id: 4, name: 'ddd', age: 15 },{ id: 5, name: 'eeee', age: 14 },{ id: 6, name: 'fff', age: 19 },{ id: 7, name: 'ggg', age: 20 },{ id: 8, name: 'hhh', age: 21 },{ id: 9, name: 'iii', age: 22 },{ id: 10, name: 'jjj', age: 23 },
])const currentPage = ref(1)
const pageSize = ref(5)
const multipleSelection = ref<number[]>([])const paginatedData = computed(() => {const start = (currentPage.value - 1) * pageSize.valueconst end = start + pageSize.valuereturn tableData.value.slice(start, end)
})const getSelectedData = () => {console.log('Selected data:', multipleSelection.value)
}const setSelectedData = () => {multipleSelection.value = [2, 8]
}const handleCheck = (e,id) => {if(e) {multipleSelection.value.push(id)} else {const index = multipleSelection.value.findIndex(item => item.id === id)multipleSelection.value.splice(index, 1)}
}
</script><template><div class="table-container"><el-table:data="paginatedData"style="width: 100%"><el-table-column header-align="center" align="center" width="40"><template #default="scope"><el-checkbox :model-value="multipleSelection.includes(scope.row.id)" @change="handleCheck($event, scope.row.id)" /></template></el-table-column><el-table-columnprop="name"label="名字"/><el-table-columnprop="age"label="年龄"/></el-table><div class="footer"><el-paginationv-model:current-page="currentPage":page-size="pageSize":total="tableData.length"layout="prev, pager, next"/><div class="buttons"><span class="selected-info">已选择: {{ multipleSelection.length }}</span><el-button type="primary" @click="getSelectedData">获取选中的数据</el-button><el-button type="primary" @click="setSelectedData">渲染数据</el-button></div></div></div>
</template><style scoped>
.table-container {width: 100%;max-width: 800px;margin: 0 auto;
}.footer {margin-top: 20px;display: flex;justify-content: space-between;align-items: center;
}.buttons {display: flex;align-items: center;gap: 16px;
}.selected-info {margin-right: 16px;
}
</style>

实现效果如下:
在这里插入图片描述

http://www.xdnf.cn/news/599653.html

相关文章:

  • MCP协议:AI时代的“万能插座”,如何重塑互联网技术生态?
  • Linux的启动流程
  • 华为仓颉语言生成的程序的分发部署
  • Basic concepts for seismic source - Coulomb failure stress change
  • C++内存复制
  • (01)华为GaussDB((基于PostgreSQL))高斯数据库使用记录,dbeaver客户端配置高斯驱动,连接高斯数据库
  • 订单越来越到导致接口列表查询数据缓慢解决思路
  • 【结构体宏定义】C语言结构体与宏定义:传感器配置的巧妙结合
  • 高等数学-求导
  • 计算机组成体系结构
  • 数据库-数据处理
  • B2160 病人排队
  • 算法题(153):哈夫曼编码
  • CAD打印没有标注解决方法
  • vue2实现元素拖拽
  • Git实战演练,模拟日常使用,快速掌握命令
  • “轩辕杯“云盾砺剑 CTF挑战赛web方向题解
  • 【AI论文】VisualQuality-R1:通过强化学习进行推理诱导的图像质量评估
  • 【Java】异常的初步认识
  • 1.2 Box以及 InsideBox的使用
  • python字符串
  • fastadmin添加管理员账号只能查看一个表中指定条件的数据
  • 【朝花夕拾】S32K144 backdoor key解锁后劳德巴赫或者JLINK更新app
  • Python3 批量处理银行电子回单
  • 深搜题(如何找到进入下一层深搜的条件)
  • 第十九章 ADC——电压采集
  • ZeroMQ Sockets介绍及应用示例
  • 01_消息中间件概述
  • for...in 和 for...of:用法、区别
  • Vue2 项目报错问题收录(持续更新...)