feat: GrTable 移动端表格组件 + manager/Projects 试点

业务背景
- 项目里 17+ 列的列表页 (manager/Projects, Meetings, AdminUsers 等) 在手机端只能
  横向滚动, 操作体验差.
- refer/gr-table.vue 是 Vue2 + Vant 组件, Vue3 不能直接用 (componentOptions
  私有 API 已被 Vue3 移除).
- 新建 Vue3 + EP 兼容版本 GrTable, 吸收"主列显示 / 次要列折叠到展开行"思想.

组件设计
- props: data, mainCols (默认 = 第一个 prop + 最后一个 prop), mobileBreakpoint
- 通过 slots.default() 取 vnode, 读 vnode.props.prop/label (Vue3 思路, 替代
  Vue2 componentOptions 私有 API)
- v-bind="\$attrs" 全透传 el-table 原生 props/events
- el-table 引用方法 (clearSelection / toggleRowSelection 等) defineExpose
  暴露

manager/Projects 试点
- 引入 GrTable, :main-cols="['projectNo', 'projectName']"
- 手机端: 只显示项目编号 + 项目名称 + 操作列, 其他 13 列折叠到展开行
- 桌面端: 与原 el-table 完全一致 (所有 17 列)
- 操作列 (label=操作, 无 prop) 自动保留 (因为 shouldRenderColumn 跳过无 prop 列)
This commit is contained in:
guoju0808
2026-08-26 11:32:53 +00:00
parent 02715a1385
commit 0644e26120
5 changed files with 560 additions and 2 deletions
+10 -2
View File
@@ -81,7 +81,14 @@
批量删除<span v-if="selection.length" class="badge">{{ selection.length }}</span>
</el-button>
</div>
<el-table :data="rows" v-loading="loading" stripe border @selection-change="onSel">
<GrTable
:data="rows"
v-loading="loading"
stripe
border
:main-cols="['projectNo', 'projectName']"
@selection-change="onSel"
>
<el-table-column type="selection" width="44" />
<el-table-column prop="projectNo" label="项目编号" width="140" fixed="left" />
<el-table-column prop="projectName" label="项目名称" min-width="200" show-overflow-tooltip />
@@ -140,7 +147,7 @@
</div>
</div></template>
</el-table-column>
</el-table>
</GrTable>
<el-pagination v-model:current-page="page.pageNum" v-model:page-size="page.pageSize" :total="page.total" :page-sizes="[10,20,50]" layout="total, sizes, prev, pager, next, jumper" @current-change="load" @size-change="load" />
</div>
@@ -245,6 +252,7 @@ import request from '@/utils/request'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowDown } from '@element-plus/icons-vue'
import Preview from '@/components/Preview.vue'
import GrTable from '@/components/GrTable.vue'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
const router = useRouter()