☰
wot-design-uni Table 表格组件完全指南:数据展示、固定列、排序与分页实战
2026/10/14 3:09:21 网站建设 项目流程
  • 前端
  • UI组件
  • 移动开发
  • 小程序

【免费下载链接】wot-design-uni

一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。

项目地址:https://gitcode.com/gh_mirrors/wo/wot-design-uni
点击查看免费下载

导读

wd-table是 wot-design-uni 中用于展示多条结构类似数据的表格组件,通过wd-table-col子组件声明列结构,配合data数据源即可渲染完整表格,并内置了列排序、固定列、斑马纹、固定表头、索引列与自定义列模板等能力。本文以 docs/component/table.md 官方文档为骨架,结合 wd-table.vue、wd-table-col.vue 等源码实现与 wd-table.test.ts 测试用例,完整讲解表格的配置项、事件与插槽,并给出可与分页器联动的实战方案。读完本文,你将能在 uni-app 项目中快速搭建可排序、可固定列、可自定义单元格、可分页的数据表格。

版本注意:1.5.0起取消了height的默认值,需要自行设置,且官方建议优先使用number类型,方便未来适配虚拟列表。

组件构成与数据模型

表格由两个组件协作组成:

  • wd-table:表格容器,负责接收data数据、管理高度/边框/斑马纹等全局配置,并通过@sort-method、@row-click抛出事件;
  • wd-table-col:列定义,通过prop绑定数据字段、label设置表头文案,并支持sortable、fixed、align、width等列级配置。

从源码看,wd-table通过useChildren(TABLE_KEY)(wd-table.vue)建立与子列wd-table-col的关联,列组件内部则从table.props.data中按prop字段提取该列全部单元格数据(wd-table-col.vue),即data为对象数组、每列由prop映射字段的经典模型。

基础用法

通过data设置表格数据,并在wd-table内声明若干wd-table-col定义列:

<wd-table :data="dataList" :height="400"> <wd-table-col prop="name" label="姓名"></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>
import { reactive } from 'vue' const dataList = reactive([ { name: '赵云', school: '武汉市阳逻妇幼保健学院', major: '计算机科学与技术专业' }, { name: '孔明', school: '武汉市阳逻卧龙学院', major: '计算机科学与技术专业' }, { name: '刘备', school: '武汉市阳逻编织学院', major: '计算机科学与技术专业' } ])

从源码结构看,data是makeRequiredProp(Array<Record<string, any>>)必填属性(types.ts),不传将无法渲染数据;渲染时每列按prop取item[prop]作为单元格文本(wd-table-col.vue),若取不到则渲染空内容。

固定列

通过fixed设置表格列是否固定展示,默认false。固定后该列在横向滚动时会始终停留在可视区域左侧,便于在列数较多时保留关键信息:

<wd-table :data="dataList" :height="400"> <wd-table-col prop="name" label="姓名" fixed></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>

::: warning 提示 目前仅支持固定在左侧,且固定列组件的排列顺序要和实际想要展示的顺序相同。 :::

源码实现要点(便于理解固定列的底层机制):

  • 固定列样式基于position: sticky+left偏移实现,z-index: 1保证其覆盖在普通列之上(index.scss);
  • 第 N 个固定列的left值为它前面所有列宽度之和,通过calc(...)计算得出(wd-table.vue),测试用例也验证了「第二固定列 left 为 calc(100px)」这一行为(wd-table.test.ts);
  • 当横向滚动发生时,最后一个固定列右侧会追加一层渐隐阴影,提示其后仍有内容可滚动(wd-table.vue),阴影渐隐效果定义在 index.scss。

显示索引

通过index设置表格是否显示序号列,默认false。除布尔值外,也可以传入对象对序号列进行配置,参数同TableColumnProps(不含prop):

<!-- 简单开启索引列 --> <wd-table :data="dataList" :index="true" :height="400"> <wd-table-col prop="name" label="姓名" sortable></wd-table-col> <wd-table-col prop="grade" label="分数" sortable></wd-table-col> <wd-table-col prop="hobby" label="一言以蔽之" sortable :width="160"></wd-table-col> </wd-table> <!-- 自定义索引列:居中、宽度 200 --> <wd-table :data="dataList" :index="{ align: 'center', width: 200 }"> <wd-table-col prop="name" label="姓名" sortable align="center"></wd-table-col> <wd-table-col prop="grade" label="分数" sortable align="center"></wd-table-col> <wd-table-col prop="hobby" label="一言以蔽之" sortable :width="160"></wd-table-col> </wd-table>

源码实现要点:

  • 源码中index的类型为boolean | Omit<Partial<TableColumnProps>, 'prop'>,默认false(types.ts);
  • 索引列本质是表格内部注入的一列wd-table-col,其#value插槽渲染{{ index + 1 }},即从 1 开始计数(wd-table.vue);
  • 索引列默认配置为:label取组件内部国际化翻译indexLabel(简体中文下为「序号」,见 locale/lang/zh-CN.ts)、width: 100rpx、align: 'left',传入对象时用展开合并覆盖默认值(wd-table.vue),测试用例验证了默认 label「序号」与自定义 label「编号」的生效(wd-table.test.ts)。

斑马纹

通过stripe设置表格是否展示斑马纹,默认true。关闭后所有行背景一致:

<wd-table :data="dataList" :stripe="false" :height="400"> <wd-table-col prop="name" label="姓名"></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>

斑马纹在源码中通过「奇数行」判定实现:wd-table-col内部使用isOdd(index)判断行号奇偶,命中则追加is-stripe类(wd-table-col.vue),背景色取自主题变量$-table-stripe-bg(index.scss),并支持暗黑模式下的对应配色(index.scss)。

边框

通过border设置表格是否展示边框,默认true。开启时表格外框、单元格间分隔线均可见:

<wd-table :data="dataList" :border="false" :height="400"> <wd-table-col prop="name" label="姓名"></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>

源码中border默认值为true(types.ts),开启时根节点追加is-border类(wd-table.vue),样式层为表格容器增加 1px 外边框、为单元格增加右边框与下边框(index.scss、index.scss),最后一列右边框会被去除以保持视觉闭合(index.scss)。

表格高度与固定表头

通过height设置表格高度,设置高度后会自动固定表头(fixed-header默认为true,需要结合height才能实现固定表头效果):

<wd-table :data="dataList" :height="400"> <wd-table-col prop="name" label="姓名"></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>

源码实现要点:

  • height类型为number / string(无默认值),传入后容器样式的max-height生效(wd-table.vue),测试用例验证了height: 300时会得到max-height: 300px(wd-table.test.ts);
  • 表头行高与数据行高是分开计算的:数据区高度按data.length * rowHeight(默认每行 50px)计算,使滚动容器可以精确滚动(wd-table.vue);
  • 固定表头模式下,表头使用独立的scroll-view并通过scrollLeft与数据区联动,保持横向滚动同步(wd-table.vue);表头容器本身position: sticky; top: 0; z-index: 2(index.scss);
  • 行高通过rowHeight控制,默认50(types.ts),作用于每个单元格的height(wd-table-col.vue)。

排序与排序事件

当列设置sortable后,表头会出现排序按钮(内部使用wd-sort-button组件,见 wd-table.vue),点击会触发sort-method排序事件:

<wd-table :data="dataList" @sort-method="handleSort" :height="400"> <wd-table-col prop="name" label="姓名"></wd-table-col> <wd-table-col prop="school" label="求学之所" sortable></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> </wd-table>
function handleSort(e) { console.log('这里是排序事件') }

事件参数与排序方向:

  • sort-method的回调参数为当前点击列的数据TableColumn,包含prop、label、width、sortable、align、fixed以及sortDirection字段(wd-table.vue);
  • sortDirection取值为0 | 1 | -1(wd-table-col/types.ts):1升序、-1降序、0取消排序;组件本身不负责数据重排,需要你在事件回调中根据方向自行处理dataList;
  • 同一时刻仅允许一列参与排序:切换排序列时,其余列的sortDirection会被重置为0(wd-table.vue),测试用例完整验证了「升序 → 降序 → 取消」的状态流转与其余列重置行为(wd-table.test.ts)。

自定义列模板(Scoped Slot)

自定义列的显示内容,可组合其他组件使用。通过#value插槽可以获取到row、index数据,适用于展示富文本、标签、按钮等复合内容:

<wd-table :data="dataList" @sort-method="handleSort" :height="400"> <wd-table-col prop="name" label="姓名" fixed="true" width="320rpx" sortable></wd-table-col> <wd-table-col prop="grade" label="分数" width="220rpx" sortable> <template #value="{row}"> <view class="custom-class"> <text>{{ row.grade }}</text> <text>同比{{ row.compare }}</text> </view> </template> </wd-table-col> <wd-table-col prop="hobby" label="一言以蔽之" sortable></wd-table-col> <wd-table-col prop="school" label="求学之所"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> <wd-table-col prop="gender" label="性别"></wd-table-col> <wd-table-col prop="graduation" label="学成时间"></wd-table-col> </wd-table>
import { ref } from 'vue' interface TableData { name: string school: string major: string gender: string graduation: string grade: number compare: string hobby: string } const dataList = ref<TableData[]>([ { name: '张飞', school: '武汉市阳逻杀猪学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 56, compare: '10%', hobby: '燕人张飞在此!' }, { name: '关羽', school: '武汉市阳逻绿豆学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 66, compare: '11%', hobby: '颜良文丑,以吾观之,如土鸡瓦犬耳。' }, { name: '刘备', school: '武汉市阳逻编织学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 45, compare: '1%', hobby: '我得空明,如鱼得水也' }, { name: '赵云', school: '武汉市阳逻妇幼保健学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 69, compare: '14%', hobby: '子龙,子龙,世无双' }, { name: '孔明', school: '武汉市阳逻卧龙学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 88, compare: '21%', hobby: '兴汉讨贼,克复中原' }, { name: '姜维', school: '武汉市阳逻停水停电技术学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 87, compare: '32%', hobby: '我计不成,乃天命也!' } ]) /** * 排序:仅示意,实际应根据 sortDirection 决定升/降序 */ function handleSort(e) { dataList.value = dataList.value.reverse() }
.custom-class { height: 80rpx; width: 220rpx; display: flex; flex-direction: col; align-items: center; }

插槽实现说明:#value插槽由wd-table-col在每个数据单元格上渲染,作用域参数为{ row, index }(row为当前行完整对象,index为行下标,1.2.16起新增index参数),未提供插槽时默认渲染纯文本{{ row }}(wd-table-col.vue);row数据经由getScope(index)从table.props.data[index]取出(wd-table-col.vue)。官方 demo 中该自定义列模板也使用了同样的写法(src/subPages/table/Index.vue)。

不固定表头结合分页器使用

在数据量较大的场景下,可设置fixed-header为false取消固定表头,再配合wd-pagination组件实现分页加载。通过v-model绑定分页器当前页码,通过total设置分页器总条数,并使用computed按页码与每页条数对数据切片:

<wd-table :data="paginationData" :height="400" :fixed-header="false"> <wd-table-col prop="name" label="姓名" fixed align="center"></wd-table-col> <wd-table-col prop="grade" label="分数" fixed align="center"></wd-table-col> <wd-table-col prop="hobby" label="一言以蔽之" :width="160"></wd-table-col> <wd-table-col prop="school" label="求学之所" :width="180"></wd-table-col> <wd-table-col prop="major" label="专业"></wd-table-col> <wd-table-col prop="gender" label="性别"></wd-table-col> </wd-table> <wd-pagination custom-style="border: 1px solid #ececec;border-top:none" v-model="page" :total="total"></wd-pagination>
import { computed, ref } from 'vue' interface TableData { name: string school: string major: string gender: string graduation: string grade: number compare: string hobby: string } const dataList = ref<TableData[]>([ // 此处为完整数据集,可包含数十条记录 { name: '关羽', school: '武汉市阳逻绿豆学院', major: '计算机科学与技术专业', gender: '男', graduation: '2022年1月12日', grade: 66, compare: '48%', hobby: '颜良文丑,以吾观之,如土鸡瓦犬耳。' } // ... ]) const page = ref<number>(1) const pageSize = ref<number>(10) const total = ref<number>(dataList.value.length) const paginationData = computed(() => { // 按页码和每页条数截取数据 return dataList.value.slice((page.value - 1) * pageSize.value, page.value * pageSize.value) })

原理与注意点:

  • fixed-header默认true(types.ts),关闭后组件切换为「单个 scroll-view 内依次渲染表头行 + 内容行」的结构(wd-table.vue),此时表头随内容一同滚动,便于分页器贴在表格底部时整体结构更紧凑;
  • 分页本质是前端切片:paginationData根据(page - 1) * pageSize与page * pageSize截取数据,页码变化时wd-table的data随之更新,触发重渲染;
  • 官方 demo(src/subPages/table/Index.vue)与本文示例一致,分页器通过custom-style与表格衔接,消除顶部边框形成一体式外观。该方案适合数据量中等、无需后端分页的中后台与 H5 场景;数据量极大时建议改为服务端分页,仅向表格传入当前页数据。

Attributes(表格配置项)

参数说明类型可选值默认值最低版本
data显示的数据(必填,对象数组,每项按prop取字段)Array--0.0.39
border是否带有边框boolean-true0.0.39
stripe是否为斑马纹表boolean-true0.0.39
heightTable 的高度,无默认值,设置后自动开启固定表头number / string--0.0.39
rowHeight行高number / string-500.0.39
showHeader是否显示表头boolean-true0.0.39
ellipsis是否超出 2 行隐藏boolean-true0.0.39
index是否显示索引列,可传入boolean也可传入 column 配置boolean / TableColumnProps-false1.2.19
fixed-header是否固定表头,需要结合height才可以实现固定表头的效果boolean-true1.5.0

补充说明(源码级):

  • rowHeight默认50(types.ts),传入字符串时会经addUnit归一化处理;
  • ellipsis默认true,超出 2 行自动截断,样式上通过word-break: break-all配合multiEllipsis(2)实现两行省略(index.scss);
  • showHeader默认true,置false后表头整段不渲染(wd-table.vue);
  • 除上述业务属性外,组件还继承了customStyle、customClass等基础属性(baseProps,types.ts),用于覆盖容器样式与类名,测试用例亦有覆盖(wd-table.test.ts)。

Events(表格事件)

事件名称说明参数最低版本
sort-method指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 的时候有效TableColumn:当前点击列数据0.0.39
row-click当某一行被点击时会触发该事件{ rowIndex: number }点击行的下标0.0.39

事件行为细节:

  • sort-method由表头排序按钮触发,TableColumn参数结构见 wd-table-col/types.ts,其中sortDirection为0 | 1 | -1;
  • row-click由wd-table-col的单元格点击上抛:单元格@click调用handleRowClick(index),最终由wd-table统一 emit{ rowIndex: index }(wd-table-col.vue、wd-table.vue),测试用例验证了载荷为{ rowIndex: 0 }(wd-table.test.ts)。

TableColumn Attributes(列配置项)

参数说明类型可选值默认值最低版本
prop字段名称,对应列内容的字段名string--0.0.39
label显示的标题string--0.0.39
width对应列的宽度,单位为 pxnumber / string-1000.0.39
sortable是否开启列排序boolean-false0.0.39
fixed是否固定本列boolean-false0.0.39
align列的对齐方式AlignTypeleft, center, rightleft0.0.39

源码级补充:

  • prop与label均为必填(makeRequiredProp),缺失时类型层面即报错(wd-table-col/types.ts);
  • width默认100,传入字符串如'320rpx'同样会被addUnit归一化后写入单元格样式(wd-table-col/types.ts、wd-table-col.vue);
  • align类型为AlignType(left | center | right),在样式层映射为justify-content: flex-start / center / flex-end(wd-table-col/types.ts、index.scss);
  • fixed生效时,表头与数据单元格同时应用sticky定位(表头侧见 wd-table.vue,数据侧见 wd-table-col.vue)。

TableColumn Slot(列插槽)

name说明参数最低版本
value自定义列的内容,1.2.16 新增index参数{ row: Object, index: number }0.1.22

使用示例:

<wd-table-col prop="grade" label="分数"> <template #value="{ row, index }"> <text>第 {{ index + 1 }} 行:{{ row.grade }} 分</text> </template> </wd-table-col>

#value插槽与数据行的渲染一一对应:每行一个插槽实例,row为该行原始对象,index为该行在data中的下标,可在此基础上自由组合wd-tag、wd-button等其他组件实现富单元格。

小结

wd-table以「容器 + 列声明」的简洁模型覆盖了移动端表格的大部分刚需:fixed固定列解决横向滚动时关键信息丢失的问题,sortable+sort-method提供完整的升/降序/取消交互,height+fixed-header控制滚动与表头吸附,index内置序号列,#value插槽支持完全自定义单元格;配合wd-pagination可以快速搭建前端分页表格。需要特别留意的限制包括:1.5.0起height无默认值需自行设置、固定列目前仅支持左侧且声明顺序须与展示顺序一致、排序仅抛出方向事件需自行处理数据重排。相关源码与测试可进一步查阅 wd-table.vue、wd-table-col.vue、types.ts 与 wd-table.test.ts。

  • 前端
  • UI组件
  • 移动开发
  • 小程序

【免费下载链接】wot-design-uni

一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。

项目地址:https://gitcode.com/gh_mirrors/wo/wot-design-uni
点击查看免费下载
上一篇:speech-to-speech 项目 LLM 后端接入指南:Transformers、MLX-LM 与 OpenAI 兼容 API 的配置与原理全解析
下一篇:ArduPilot 支持 NxtPX4v2 飞控硬件详解:接口映射、参数默认值与固件刷写实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询