更新记录
0.3.0(2026-09-30)
下载此版本
- 新增表头 / 合计行底色配置:组件 props
headerBackgroundColor / summaryBackgroundColor(16 进制或任意 CSS 颜色字面量,内联渲染,可从业务数据动态给色、App 蒸汽模式同样生效);同时新增组件级 token --nax-table-header-bg / --nax-table-summary-bg(优先于全局 --nax-color-bg-secondary,只影响本表格),三者优先级:prop > 组件 token > 全局 token;不传时观感与之前完全一致(固定列表头、固定合计行同步生效)
- 序号列(
type: 'index')支持 formatter:配了 formatter 时由业务接管编号渲染(如 'No.' + (index + 1)、补零、加前缀),index 为 data 绝对下标;不配时行为不变(仍为 index + 1,从 1 开始,排序 / 内部分页 / 虚拟滚动下连续)
- 新增日期编辑:列配置
editor(date / datetime / time / year / year-month / month-day)+ editable: true 后点击单元格弹日期选择,确认后与文本编辑同样提交 cell-edit(组件仍不改 data);新增列字段 minDate / maxDate(可选范围,'YYYY-MM-DD' 或带时间)与 showSecond(datetime / time 显示秒列)
- 日期编辑写回值按原值类型:原值为数字 → 时间戳(number);字符串 → 按列
format(缺省用编辑器默认模板,如 YYYY-MM-DD / HH:mm)格式化后的字符串;cell-edit 的 oldValue / value 语义与文本编辑一致(值未变化不触发)
- 弹层实现:
nax-datetime-picker 单实例挂在表格根节点(编辑态单例),按列配置 v-if 挂载,未配日期列时不引入实例;uni_modules.dependencies 新增 nax-datetime-picker
- 微信小程序端:
date / year-month / time(未开 showSecond)用微信原生 picker(mode="date" + fields 控制粒度 / mode="time");微信系统弹层只能由用户点击触发,故交互为「点单元格进入编辑态 → 再点单元格内的选择框弹出」,单元格内容即触发区(条件编译 #ifdef MP-WEIXIN)
- 微信端
datetime / month-day / time + showSecond 无法映射微信 picker(无对应 mode / 无秒列),退回组件自建弹层,与其它端交互一致
- 修复固定列层的行/列下标错用本地下标:固定列覆盖层的
row-click、多选勾选态与 isEditingCell / cell-edit 的 colIndex 会取到「固定列内序号」或「窗口内行号」而非绝对下标(虚拟滚动 / 分页 + 固定列组合下选中态与编辑态可能错位,序号列与文本数量也可能不一致);现统一经 absIndex / fixedColIndex 换算,非固定列场景行为不变
- 新增列配置
backgroundColor(16 进制):自定义可编辑单元格的编辑框底色,展示态(灰底虚线框)与编辑态(输入框)共用同一底色,点击前后不会突然变色;内联字面量渲染,App 蒸汽模式同样生效(原生节点 var() 不可靠),Web / 小程序行为一致;仅 editable: true 的列生效,不传时沿用原 token(展示态 --nax-color-bg-hover、编辑态 --nax-color-bg),默认观感不变;固定列正文同步生效
0.2.0(2026-09-29)
下载此版本
- 新增
editGap prop(boolean,默认 true 保持原样):edit-gap="false" 时编辑框铺满单元格,消除相邻可编辑列之间由「单元格左右内边距」形成的空隙;左右内边距改由内部 text/input 承担,文字仍与只读列对齐;固定列正文同步支持(表头保持 12px 不位移)
- 修复可编辑单元格进入编辑态后文字跳回左对齐:编辑输入框此前不带
text-align(原生 input 默认左对齐),align: 'right' / 'center' 的列点进去即丢对齐;现按列 align 输出 text-align,进出编辑态位置一致
- 修复 date 列
format 模板大小写敏感:yyyy-mm-dd 这类小写模板此前只有 mm(分钟占位)被替换,yyyy / dd 原样残留(实际渲染成 yyyy-00-dd);现模板大小写不敏感(yyyy-mm-dd 与 YYYY-MM-DD 等价),mm 歧义按 Excel 习惯消解——出现在 hh 之后按分钟、否则按月份,并新增 yy 两位年
- 修复 date 列日期串解析的跨端/时区不一致:字符串先自行拆分量再
new Date(y, m-1, d, h, mi, s) 构造本地时间,避免纯日期串在 Web 被按 UTC 解析后用本地分量取值差一天;自解析失败时按 - → / 归一化交平台解析(同 nax-datetime-picker),带时区标识(Z / ±偏移)的串仍交回平台解析(原行为不变)
- 修复 Web / 微信小程序可编辑单元格展示态底色框比单元格宽出左右内边距(
<text> 默认 content-box):补 box-sizing: border-box,与 App 端观感对齐;条件编译 #ifndef APP-ANDROID || APP-IOS || APP-HARMONY,App 三端行为不变
- number 列
format(#,###.00 千分位、0.0% 百分比)与既有 props / events 行为不变,属向后兼容新增与修复
0.1.0(2026-09-28)
下载此版本
- 初版
nax-table(uni-app x / 蒸汽模式),columns + data 数据驱动的数据表格
- 列类型 text / index / operation / selection;
stripe 斑马纹、border 单元格边框、highlight 行点击高亮
- 固定表头(表头位于纵向滚动区外,
height 有值时表体独立滚动)+ 列宽超出容器时横向滚动
- 文本列
lines 多行省略、emptyString 空值占位、formatter 自定义单元格文本、align / headerAlign 对齐、color 单元格文字色
- 排序:
sorter: true 组件内部排序(受控外观 + sort-change)/ sorter: 'custom' 仅 emit sort-change 由业务处理
- 多选:
type: 'selection' 表头全选 / 半选 + selection-change;列 selectable 控制行是否可勾选(禁用行不参与全选)
- 合计行
showSummary / sumText / summaryMethod(cell 支持 colspan 跨列)、分组表头 groupTitle(相邻同名合并)
- 分页
showPaging(inner 组件切片 / outer 受控 + page-change)、加载更多 showLoadMore / finished + load-more
- 固定列
fixed(左侧覆盖层 + 主区 @scroll 纵向单向同步)、虚拟滚动 virtual + rowH(spacer 占位 + 窗口裁剪)
- 可编辑单元格
editable(cell-edit 提交,组件不修改 data);行焦点 row-blur;操作列 renders + action
- 实例方法:
resetHighlight / clearSelection / toggleRowSelection / toggleAllSelection / clearSort / resetPage
- 依赖
nax-empty、nax-icon、nax-ui-theme
查看更多
平台兼容性
uni-app x(4.25)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| √ |
√ |
√ |
√ |
√ |
√ |
其他
| 多语言 |
暗黑模式 |
宽屏模式 |
蒸汽模式 |
| × |
√ |
× |
× |
nax-table 表格
nax-ui 数据表格组件(uni-app x / 蒸汽模式)。columns + data 数据驱动:斑马纹 / 边框、固定表头 + 横向滚动、排序、行数省略、空态、多选、合计行、分组表头、分页、加载更多、固定列、虚拟滚动,以及可编辑单元格(文本输入 / 日期选择)、序号列自定义编号、表头与合计行底色配置。
引入
easycom 自动注册,页面直接使用 <nax-table />,无需 import。
基础用法
<template>
<nax-table :data="list" :columns="cols" stripe border @row-click="onRow"></nax-table>
</template>
<script setup>
import { NaxTableColumn } from '@/uni_modules/nax-table/components/nax-table/table-types.uts'
const cols = [
new NaxTableColumn({ name: 'name', label: '姓名', width: '90' }),
new NaxTableColumn({ name: 'age', label: '年龄', width: '70', sorter: true }),
new NaxTableColumn({ label: '#', type: 'index', width: '50' })
]
const list = [
{ name: '张三', age: 24 },
{ name: '李四', age: 31 }
]
</script>
列类型
| type |
说明 |
text(默认) |
普通文本列,取 row[col.name] |
index |
序号列,默认展示行号(从 1 开始,取 data 绝对下标:排序/分页/虚拟滚动下连续);配 formatter 可自定义编号(如 'No.' + (index + 1)),表头文案用 label(缺省 #) |
operation |
操作列,配合 renders 渲染按钮 |
selection |
多选列,表头为全选/半选框 |
分组表头
列配置 groupTitle 相邻相同即合并为一组(一级分组);无 groupTitle 的列不参与分组行。
可编辑单元格
列配置 editable: true 后点击单元格进入输入态,失焦或回车(确认)提交 cell-edit:
<template>
<nax-table :data="list" :columns="cols" @cell-edit="onCellEdit"></nax-table>
</template>
<script setup>
import { NaxTableColumn, NaxTableCellEditPayload } from '@/uni_modules/nax-table/components/nax-table/table-types.uts'
const cols = [
new NaxTableColumn({ name: 'name', label: '姓名', width: '120', editable: true }),
new NaxTableColumn({ name: 'age', label: '年龄', width: '100', align: 'right', dataType: 'number', editable: true, backgroundColor: '#daefe4' }),
new NaxTableColumn({ name: 'brd', label: '生日', width: '140', editor: 'date', format: 'YYYY-MM-DD', editable: true })
]
const list = [
{ name: '张三', age: 24, brd: '1985-07-02' },
{ name: '李四', age: 31, brd: '1995-07-02' }
]
function onCellEdit(payload : NaxTableCellEditPayload, row : any) {
// 组件不改 data:必须回写,否则单元格保持旧值
row[payload.name] = payload.value
uni.showToast({ title: payload.value.toString(), icon: 'none' })
}
</script>
- 回写是必须的:组件只 emit
cell-edit,不修改 props.data;业务不回写时单元格会保持旧值(不是提交失败,而是数据源没变)
- 编辑态与展示态对齐一致:列
align: 'right' / 'center' 时输入框内文字同样右对齐 / 居中
- 编辑框底色:列
backgroundColor(16 进制)同时作用于展示态灰框与编辑态输入框,点击前后不会突然变色;字面量色值不随主题变化(暗色主题下需自行给深色值),不传时走主题 token(展示态 --nax-color-bg-hover、编辑态 --nax-color-bg)
editGap(默认 true)控制编辑框与单元格左右边缘的空隙;edit-gap="false" 时编辑框铺满单元格、相邻可编辑列之间无缝,文字仍与只读列对齐
dataType: 'number' 提交时自动转数值;输入无法解析为数值(清空、含非数字字符等)时回退原值并仍会触发 cell-edit(payload.value 与 payload.oldValue 相等即本次未改变值)
- 编辑态为单例:同一时刻只有一个单元格处于输入态,切换单元格即提交上一个
- 日期编辑:列配
editor(date / datetime / time / year / year-month / month-day)+ editable: true 后,点击单元格弹日期选择(minDate / maxDate 限范围,showSecond 给 datetime / time 加秒列),确认后同样提交 cell-edit;写回值按原值类型:原值是数字 → 时间戳(number),字符串 → 按列 format(缺省用编辑器默认模板,如 YYYY-MM-DD)格式化的字符串
- 日期编辑不出现文本输入框,单元格保持展示态(
editGap / backgroundColor 等对日期列同样生效)
字段格式化(dataType + format)
| dataType |
format 示例 |
原始值 |
展示 |
date |
YYYY-MM-DD(等价 yyyy-mm-dd) |
1985-07-02 |
1985-07-02 |
date |
yyyy/MM/dd HH:mm:ss |
1985-07-02 08:05:00 |
1985/07/02 08:05:00 |
number |
#,###.00 |
1234567.891 |
1,234,567.89 |
number |
0.0% |
0.456 |
45.6% |
- 日期模板大小写不敏感,token:
yyyy / yy 年、mm 月或分、dd 日、hh 时、ss 秒;mm 出现在 hh 之后按分钟、否则按月份(因此 YYYY-MM-DD HH:mm:ss 与 yyyy-mm-dd 都能按预期工作)
- 日期串优先自行拆分量构造本地时间(规避纯日期串按时区差一天与 App 端字符串解析差异),无法解析时按原值展示
dataType: 'string' 不套用 format;列 formatter / filters 优先级高于 format
Props
| 参数 |
说明 |
类型 |
默认值 |
data |
行数据数组 |
any[] |
[] |
columns |
列配置(NaxTableColumn[]) |
NaxTableColumn[] |
[] |
stripe |
斑马纹 |
boolean |
false |
border |
单元格边框 |
boolean |
true |
highlight |
点击行高亮 |
boolean |
false |
height |
表体高度;纯数字按 px;不传随内容不纵向滚动 |
string |
'' |
thH |
表头行高 |
string |
'40' |
headerBackgroundColor |
表头底色(16 进制或任意 CSS 颜色字面量);空则走 --nax-table-header-bg → --nax-color-bg-secondary |
string |
'' |
tdH |
单元格最小行高 |
string |
'40' |
editGap |
可编辑单元格的编辑框是否与单元格左右边缘留空隙;false 时编辑框铺满单元格、相邻可编辑列无缝 |
boolean |
true |
emptyString |
全局空值占位文案(列配置 emptyString 优先) |
string |
'' |
empty |
data 为空时是否展示内置空态 |
boolean |
true |
showSummary |
合计行开关 |
boolean |
false |
sumText |
合计行首格文案 |
string |
'合计' |
summaryBackgroundColor |
合计行底色(16 进制或任意 CSS 颜色字面量);空则走 --nax-table-summary-bg → --nax-color-bg-secondary |
string |
'' |
summaryMethod |
自定义合计 (columns, data) => NaxTableSummaryCell[];cell 支持 colspan 跨列 |
function \| null |
null |
showPaging |
分页器开关 |
boolean |
false |
pagingMode |
inner 组件内部自动切片 / outer 只 emit page-change |
string |
'inner' |
paging |
分页配置 NaxTablePaging(current/pageSize/total/pageCount/navNum/prevText/nextText) |
NaxTablePaging |
— |
showLoadMore |
加载更多开关(触底或点击触发 load-more) |
boolean |
false |
finished |
加载完成(显示「没有更多了」且不再触发) |
boolean |
false |
virtual |
虚拟滚动开关;需配合 height 与固定行高 rowH |
boolean |
false |
rowH |
虚拟滚动行高(px) |
string |
'44' |
custom-class |
根节点扩展 class |
string |
'' |
NaxTableColumn
| 字段 |
说明 |
默认值 |
name |
字段名;index/operation 列可留空 |
'' |
label |
表头文案 |
'' |
type |
text / index / operation |
text |
width |
列宽,纯数字按 px;不传均分 |
'' |
lines |
单元格最大行数 1-5,超出省略 |
1 |
align |
单元格对齐 left/center/right |
'' |
headerAlign |
表头对齐,缺省跟随 align |
'' |
groupTitle |
分组表头名;相邻相同自动合并 |
'' |
fixed |
是否固定在左侧;需显式 width(缺省按 100px) |
false |
filters |
值 → 文案映射(如 new Map([['0','男'],['1','女']])),命中展示文案、未命中回退原值 |
new Map() |
selectable |
行是否可勾选 (row, index) => boolean(仅 selection 列生效);返回 false 时勾选框置灰、不可勾选且不参与全选 |
null |
dataType |
字段类型 date/number/string(默认 string);影响 format 解析与可编辑输入键盘 |
string |
format |
展示格式:date 列用日期模板(大小写不敏感,yyyy/yy 年、mm 月或分、dd 日、hh 时、ss 秒;mm 在 hh 之后按分钟、否则按月份,如 YYYY-MM-DD HH:mm:ss);number 列 #,###.00 千分位+小数位、含 % 输出百分比 |
'' |
editable |
单元格是否可编辑:点击进入输入态(底色与只读列区分,编辑态沿用列 align 对齐),失焦/确认提交 cell-edit;配合 editGap 控制编辑框是否铺满单元格 |
false |
editor |
单元格编辑器:input 文本输入(默认)/ date 日期 / datetime 日期时间 / time 时间 / year 年 / year-month 年月 / month-day 月日;日期类需配合 editable: true,点击弹日期选择 |
'input' |
minDate |
日期类编辑器可选范围下限('YYYY-MM-DD' 或 'YYYY-MM-DD HH:mm:ss');空则不限制 |
'' |
maxDate |
日期类编辑器可选范围上限;空则不限制 |
'' |
showSecond |
datetime / time 编辑器是否显示秒列(微信端 time + 秒不可映射原生 picker,退回组件弹层) |
false |
emptyString |
空值占位文案 |
'' |
color |
单元格文字颜色(16 进制) |
'' |
backgroundColor |
可编辑单元格的编辑框背景色(16 进制,展示态与编辑态共用;内联字面量,App 蒸汽模式同样生效);仅 editable: true 的列生效 |
'' |
sorter |
是否可排序(仅 text 列):true 内部排序 / 'custom' 组件不排序、仅 emit sort-change(source='custom')由业务处理 |
false |
formatter |
自定义单元格文本 (row, index) => string;index 列配了它即接管序号渲染(index 为 data 绝对下标,默认序号为 index + 1) |
null |
renders |
operation 列按钮 NaxTableOperation[] |
[] |
NaxTableOperation
| 字段 |
说明 |
默认值 |
name |
按钮文案,同时作为 action 事件的 name |
'' |
type |
语义色 primary/success/warning/error |
primary |
Events
| 事件 |
负载 |
说明 |
row-click |
(row, index) |
行点击 |
cell-click |
(NaxTableCellPayload, row) |
单元格点击;payload 含 name / colIndex / index(data 绝对下标)/ value(未经 filters/formatter 处理的原始值) |
cell-edit |
(NaxTableCellEditPayload, row) |
可编辑单元格提交(失焦或确认);payload 含 name / colIndex / index / oldValue / value;组件不改 data,由业务更新数据源 |
row-blur |
(row, index) |
行焦点转移:点击/聚焦另一行时对上一活跃行触发(App 端无 hover/焦点语义,以活跃行切换近似) |
sort-change |
NaxTableSortState(name + order: asc/desc/'' + source: internal/custom) |
点击可排序列表头;同列循环 无→asc→desc→无。internal 组件内部排序;custom(sorter='custom')组件不排序,业务自行处理 |
action |
(NaxTableActionPayload, row) |
操作列按钮点击;payload 含 name / index |
selection-change |
any[] 选中行数组 |
多选变化;翻页/换数据自动清空 |
page-change |
NaxTablePageState(current/pageSize/pages) |
页码变化;outer 模式由业务自行请求并替换 data |
load-more |
无 |
触底或点击「加载更多」;finished=true 后不再触发 |
Slots
| 插槽 |
说明 |
empty |
自定义空态(默认内嵌 nax-empty 简化样式) |
Methods(defineExpose)
通过组件 ref 调用(uts 下需在业务侧声明 expose 类型):
| 方法 |
参数 |
说明 |
resetHighlight() |
— |
清除当前行高亮 |
clearSelection() |
— |
清空所有选中行 |
toggleRowSelection(index, selected?) |
data 绝对下标;可省略 selected 表示切换 |
勾选/取消勾选指定行;禁用行忽略 |
toggleAllSelection() |
— |
全选/取消全选当前渲染范围 |
clearSort() |
— |
排序状态复位(不改数据顺序) |
resetPage() |
— |
回到第一页 |
主题
通过 CSS 变量覆盖:
| Token |
用途 |
--nax-color-bg |
表格 / 单元格背景 |
--nax-color-bg-secondary |
表头 / 合计行 / 分页器底色(下面两个 token 的回退值) |
--nax-table-header-bg |
表头底色(优先于 --nax-color-bg-secondary,只影响本表格) |
--nax-table-summary-bg |
合计行底色(优先于 --nax-color-bg-secondary,只影响本表格) |
--nax-color-bg-hover |
行 hover 底色 |
--nax-color-border / --nax-color-border-strong |
单元格边框 / 编辑态边框 |
--nax-color-divider |
行分割线 |
--nax-color-text |
单元格文字 |
--nax-color-text-secondary |
表头 / 分页器等次要文字 |
--nax-color-text-placeholder |
空值占位 |
--nax-color-text-disabled |
禁用文字 |
--nax-color-text-inverse |
勾选标记反白色 |
--nax-color-primary / --nax-color-primary-secondary |
勾选框选中态 / 选中行底色 |
--nax-color-success / --nax-color-warning / --nax-color-error |
操作列按钮语义色 |
--nax-radius-sm / --nax-radius-md |
单元格 / 容器圆角 |
--nax-font-size-sm |
表头与单元格字号 |
依赖
nax-empty(空态占位)
nax-icon(多选勾选 / 半选标记)
nax-datetime-picker(日期类编辑器弹层,仅列配了日期类 editor 时挂载)
nax-ui-theme(可选 token)
注意
- 表头位于纵向滚动区之外,
height 有值时表体独立滚动,表头天然固定
- 列总宽超出容器时横向滚动(外层 scroll-view
scroll-x),指定了 width 的列不参与均分
- 排序为受控外观:
sorter: true 时组件内部维护排序状态并按其渲染 viewData(数值列按数值、字符串列按码点比较);sorter: 'custom' 时组件不排序、只 emit sort-change(source='custom'),业务也可完全自行处理 sort-change 后替换 data
max-lines 省略依赖文本节点能力,跨端表现以 nax-text 同源机制为准
- 合计行默认对「全为数值的 text 列」自动求和(保留 2 位);非数值列留空;
summaryMethod 传入后完全由业务控制,colspan 可跨列(跨列样式按列宽求和 / flex 计数展开)
pagingMode=inner 时 data 传全量、组件按 pageSize 切片;outer 时仅展示当前页数据 + emit page-change 由业务请求
- 多选状态按 data 绝对下标维护,
data 替换或翻页会自动清空;虚拟滚动换窗不影响已选状态;列配置 selectable 返回 false 的行勾选框置灰、不可勾选、不参与全选
- 可编辑单元格:组件不直接修改
props.data,提交 cell-edit 后由业务更新数据源(不回写则单元格保持旧值,见「可编辑单元格」);dataType: 'number' 提交时自动转数值(解析失败回退原值且仍触发 cell-edit);编辑态为单例(同时只有一个单元格在编辑)
- 行焦点转移:
row-blur 在点击另一行/单元格时对上一活跃行触发;App 端无 hover/焦点概念,为活跃行切换的近似语义
固定列(v3)
- 列配置
fixed: true 即固定在左侧;必须显式指定 width(未指定按 100px 处理)
- 实现为独立覆盖层(absolute 定位 + z-index):fixed 列渲染在覆盖层,主区对应槽位
visibility: hidden 让位,横向滚动时主区从覆盖层下方穿过
- 表体纵向同步:主区
@scroll 把 scrollTop 单向同步给固定列表体(无回环);height 未设置时(无纵向滚动)两侧自然对齐
- 序号列(
index)显示的行号、多选状态、事件 index 均为 data 绝对下标,滚动/裁剪/分页下保持一致
- 与分组表头组合时分组行暂不支持(分组行仍按主区全列渲染,覆盖层不含分组行);建议固定列与分组表头二选一
虚拟滚动(v3)
virtual: true + height + 固定 rowH(默认 44px)三者配合使用;行高不固定时不要开启
- 实现为上下 spacer 占位 + 窗口裁剪(可见区 ± 5 行),与
nax-virtual-list 同思路
- 与
showPaging(inner) 组合时窗口重置到当前页头部;与多选组合时选择按绝对下标维护
平台说明
- App(Android / iOS / 鸿蒙,蒸汽模式):支持
- Web:支持
- 微信小程序:支持;日期编辑的
date / year / year-month / time(未开 showSecond)用微信原生 picker(系统弹层不可定制,且只能由用户点击弹出——点单元格进入编辑态后,再点单元格内的选择框才弹出系统选择器);datetime / month-day / time + showSecond 无法映射,退回组件自建弹层(nax-datetime-picker),与其它端一致