创建动态表格的简易方法咨询及我的实现代码说明
简易动态表格实现优化方案
嘿,看了你现在用子组件做容器实现动态表格的思路,其实还能简化不少!先把你贴的代码片段整理出来,方便咱们一起优化:
<div class="table-responsive hidden-xs"> <table class="table table-striped" :class="tableClass"> <!-- header --> <thead class="bg-primary"> <tr class="text-nowrap"> <th v-for="item in columnData" v-if="!item.hide && !item.disable"> <div @click="sort(item.key)" v-if="item.sort" class="cursor-pointer"> <span v-html="item.title"></span> <!-- 这里应该是排序图标之类的内容吧? --> </div> <span v-else v-html="item.title"></span> </th> </tr> </thead> <!-- body --> <tbody> <tr v-for="(row, index) in tableData" :key="index"> <td v-for="item in columnData" v-if="!item.hide && !item.disable"> <!-- 单元格内容渲染区域 --> </td> </tr> </tbody> </table> </div>
下面给你几个简化方向,让这个动态表格更清爽、复用性更强:
1. 合并表头重复渲染逻辑
你现在表头里对item.title的渲染分了可排序/不可排序两种情况,其实可以用<template>包裹条件,减少重复代码和标签嵌套:
<th v-for="item in columnData" v-if="!item.hide && !item.disable" :key="item.key" > <template v-if="item.sort"> <div @click="handleSort(item.key)" class="cursor-pointer"> <span v-html="item.title"></span> <!-- 新增排序状态图标,直观展示排序方向 --> <span class="ml-1">{{ sortKey === item.key ? (sortAsc ? '↑' : '↓') : '' }}</span> </div> </template> <span v-else v-html="item.title"></span> </th>
2. 封装成通用单文件组件
把表格的核心逻辑(列配置、数据渲染、排序)都封装到一个组件里,外部只用传配置和数据,不用重复写表格结构:
<!-- DynamicTable.vue --> <template> <div class="table-responsive hidden-xs"> <table class="table table-striped" :class="tableClass"> <thead class="bg-primary"> <tr class="text-nowrap"> <th v-for="item in columnData" v-if="!item.hide && !item.disable" :key="item.key" > <template v-if="item.sort"> <div @click="handleSort(item.key)" class="cursor-pointer"> <span v-html="item.title"></span> <span class="ml-1">{{ sortKey === item.key ? (sortAsc ? '↑' : '↓') : '' }}</span> </div> </template> <span v-else v-html="item.title"></span> </th> </tr> </thead> <tbody> <tr v-for="(row, index) in sortedData" :key="index"> <td v-for="item in columnData" v-if="!item.hide && !item.disable" :key="item.key" > <!-- 支持自定义单元格内容 --> <slot v-if="item.slot" :name="`cell-${item.key}`" :row="row"></slot> <span v-else>{{ row[item.key] }}</span> </td> </tr> </tbody> </table> </div> </template> <script> export default { props: { columnData: { type: Array, required: true }, tableData: { type: Array, required: true }, tableClass: { type: String, default: '' } }, data() { return { sortKey: '', sortAsc: true } }, computed: { // 自动处理排序逻辑,不用外部传排序后的数据 sortedData() { if (!this.sortKey) return this.tableData return [...this.tableData].sort((a, b) => { if (a[this.sortKey] < b[this.sortKey]) return this.sortAsc ? -1 : 1 if (a[this.sortKey] > b[this.sortKey]) return this.sortAsc ? 1 : -1 return 0 }) } }, methods: { handleSort(key) { this.sortKey === key ? (this.sortAsc = !this.sortAsc) : (this.sortKey = key, this.sortAsc = true) // 支持外部监听排序事件 this.$emit('sort', { key: this.sortKey, asc: this.sortAsc }) } } } </script>
3. 外部使用超简单
在业务页面里,只用传入列配置和数据,甚至能自定义特殊单元格的内容:
<template> <DynamicTable :columnData="columns" :tableData="dataList" @sort="handleTableSort" > <!-- 自定义操作列的按钮 --> <template #cell-action="{ row }"> <button @click="editRow(row)" class="btn btn-sm btn-primary">编辑</button> <button @click="deleteRow(row)" class="btn btn-sm btn-danger ml-1">删除</button> </template> </DynamicTable> </template> <script> import DynamicTable from './DynamicTable.vue' export default { components: { DynamicTable }, data() { return { columns: [ { key: 'id', title: 'ID', sort: true }, { key: 'name', title: '名称' }, { key: 'createTime', title: '创建时间', sort: true }, { key: 'action', title: '操作', slot: true } ], dataList: [ { id: 1, name: '测试数据1', createTime: '2024-01-01' }, { id: 2, name: '测试数据2', createTime: '2024-01-02' } ] } }, methods: { handleTableSort(sortInfo) { console.log('当前排序规则:', sortInfo) }, editRow(row) { console.log('编辑数据:', row) }, deleteRow(row) { console.log('删除数据:', row) } } } </script>
这样一来,核心逻辑都封装在组件里,业务页面只用关心数据和配置,不用重复写繁琐的表格结构,维护起来也方便很多~
内容的提问来源于stack exchange,提问作者PamanBeruang
相关产品推荐
相关产品推荐

