更新记录

1.3.3(2026-07-03)

基础表格、多表头、多选、树形表格、异步加载、排序、操作按钮、列宽拖拽、固定列、上拉加载、分页、插槽、自定义样式、图片列等


平台兼容性

uni-app(4.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

介绍

基于 uni-app 开发的多功能表格组件,支持固定表头/首列/多列(含右固定)、排序(内置 & 自定义)、操作按钮、上拉加载更多、懒加载状态机、自适应列宽、列宽拖拽调整、多选 checkbox、图片展示与预览、单元格提示浮层、合计行、树形表格(同步/异步懒加载)、多级表头、分页、插槽自定义列渲染、H5 自定义横向滚动条等。已用于生产环境

兼容多端:H5、App-Vue、微信/阿里/百度/字节/QQ 小程序、快应用(华为/联盟)。

本组件基于 zb-table 进行二次开发,在原版基础上新增了工具栏(列设置面板)、懒加载状态机、右固定列、列宽拖拽调整、树形表格(同步/异步懒加载/按层级展开)、自定义横向滚动条、单选模式、禁止复制、自定义行样式、隐藏列等功能,并修复了列宽对齐、拖拽宽度保留等多项问题。

原项目地址:https://github.com/zouzhibin/zb-table | 原作者:zouzhibin


目录


快速使用

uni_modules 目录下直接引入即可自动注册组件:

<zb-table :columns="columns" :data="data"></zb-table>
export default {
  data() {
    return {
      columns: [
        { type: 'selection', fixed: true, width: 50 },
        { name: 'name', label: '姓名', width: 80, emptyString: '--' },
        { name: 'age', label: '年纪', sorter: false, align: 'right' },
        { name: 'sex', label: '性别', filters: { 0: '男', 1: '女' } },  // 也支持数组: [{value:0, label:'男'},{value:1, label:'女'}]
        { name: 'img', label: '图片', type: 'img' },
        { name: 'address', label: '地址' },
        { name: 'date', label: '日期', sorter: true },
        { name: 'province', label: '省份' },
        { name: 'city', label: '城市' },
        { name: 'zip', label: '邮编' },
        { name: 'operation', type: 'operation', label: '操作', renders: [
          { name: '编辑', func: 'edit' },
          { name: '删除', type: 'warn', func: 'dele' }
        ]}
      ],
      data: [
        { date: '2016-05-02', name: '王小虎1', province: '上海', sex: 0, age: 18,
          img: 'https://img1.baidu.com/it/u=300787145,1214060415&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
          city: '普陀区', address: '上海市普', zip: 200333 },
        { date: '2016-05-02', name: '王小虎2', province: '上海', sex: 0, age: 18,
          city: '普陀区', address: '上海市普', zip: 200333 },
        { date: '2016-05-02', name: '王小虎3', province: '上海', sex: 1, age: 20,
          city: '普陀区', address: '上海市普', zip: 200333 }
      ]
    }
  }
}

Table 属性

参数 说明 类型 可选值 默认值 是否必须
data 显示的数据 Array [] 必须
columns 列配置数组,详见 Column 属性 Array [] 必须
stripe 是否显示斑马纹 Boolean true / false true
fit 列宽是否自撑开(自适应内容宽度) Boolean true / false false
showHeader 是否显示表头 Boolean true / false true
border 是否带有纵向边框 Boolean true / false false
highlight 是否高亮当前行 Boolean true / false false
itemDate 高亮行匹配对象(配合 highlight 使用,通过 rowKey 匹配) Object {}
rowKey 行唯一键,用于行选择/树形表格等场景。可为 String(字段名)或 Function(返回唯一值) String / Function
showSummary 是否在表尾显示合计行 Boolean true / false false
sumText 合计行第一列的文本 String '合计'
summaryMethod 自定义合计计算方法 Function({ columns, data })
cellStyle 单元格样式回调方法,也可用固定 Object Function({row, column, rowIndex, columnIndex}) / Object
cellHeaderStyle 表头单元格样式回调方法,也可用固定 Object Function({column, columnIndex}) / Object
rowStyle 行样式回调方法,也可用固定 Object Function({row, rowIndex}) / Object
formatter 全局数据格式化函数(需 column 的 formatter 为 true 才生效),返回格式化后的字符串 Function(row, column, rowIndex, columnIndex): string
permissionBtn 动态控制操作按钮的显示隐藏,返回过滤后的 renders 数组 Function(row, renders, index): Array
headerRowHeight 表头行高 (px) Number 40
rowHeight 数据行高 (px) Number 40
height 表格高度 (px),大于0时启用固定高度+内部滚动,为0时自适应内容高度 Number 0
cellPadding 单元格内边距,如 "0px 8px 0rpx 8px" String "0px 8px 0rpx 8px"

上拉加载(传统模式)

参数 说明 类型 可选值 默认值 是否必须
isShowLoadMore 是否开启上拉加载 Boolean true / false false
pullUpLoading 上拉加载回调函数,参数 done 为函数,done() 代表还有数据继续加载,done('ok') 代表结束 Function(done)

关闭上拉加载方式 1(回调内):

pullUpLoading((done) => {
  // 请求数据...
  done()    // 还有数据,继续开启上拉加载
  done('ok') // 无数据,结束上拉加载
})

关闭上拉加载方式 2(手动调用):

this.$refs.zbTable.pullUpCompleteLoading('ok')

懒加载状态机(推荐替代传统上拉加载)

参数 说明 类型 可选值 默认值 是否必须
lazyLoad 是否启用懒加载状态机(idle/loading/noMore/error) Boolean true / false false
lazyLoadText 各状态文字配置 Object { loading: '加载中...', noMore: '没有更多了', error: '加载失败,点击重试' }
lazyLoadThreshold 懒加载触发阈值 (px),距底部多少 px 时触发加载 Number 40

分页

参数 说明 类型 可选值 默认值 是否必须
pagination 是否启用分页模式 Boolean true / false false
currentPage 当前页码(支持 .sync 双向绑定) Number 1
pageSize 每页条数 Number 10
total 总数据条数 Number 0
pageSizeOptions 每页条数选项数组 Array [10, 20, 50, 100]
showPageSizeChanger 是否显示每页条数切换器 Boolean true / false false
showQuickJumper 是否显示快速跳转输入框 Boolean true / false false

树形表格

参数 说明 类型 可选值 默认值 是否必须
treeProps 树形配置:{ children: 'children字段名', hasChildren: 'hasChildren字段名' } Object { children: 'children', hasChildren: 'hasChildren' }
treeColumnName 树节点展示的列 name,不指定则取第一个非 selection/index 列 String ''
defaultExpandAll 是否默认展开所有树节点 Boolean true / false false
defaultExpandLevel 默认展开树节点的层数(1=只展开第一层,2=展开前两层,依此类推;0或未设置则不展开) Number 0
indent 每级缩进距离 (px) Number 16
treeLoad 异步加载子节点函数,调用 resolve(childrenArray) 完成加载 Function(row, resolve)

注意:树形异步懒加载时,只有数据项显式包含 hasChildren: true 才会显示展开箭头并触发 treeLoad,否则视为叶子节点。

列宽拖拽调整

参数 说明 类型 可选值 默认值 是否必须
resizable 是否启用列宽拖拽调整 Boolean true / false false
resizeMinWidth 拖拽调整时的最小列宽 (px) Number 40

横向滚动条(H5 PC端)

参数 说明 类型 可选值 默认值 是否必须
showHScrollbar 自定义横向滚动条显示策略 Boolean / String true=始终显示, false=始终隐藏, "auto"=窗口宽度>720px时显示 "auto"

说明:H5 端在表格底部提供了自定义横向滚动条,支持鼠标拖拽滑块和点击轨道跳转,移动端支持触摸拖动。showHScrollbar 默认 "auto" 模式下,PC 端(窗口宽度 > 720px)自动显示滚动条,移动端自动隐藏,使用原生滑动。

工具栏(列设置面板)

参数 说明 类型 可选值 默认值 是否必须
toolbar 是否显示工具栏(列设置按钮,支持列显隐、对齐、固定、拖拽排序等) Boolean true / false false
singleSelect 是否单选模式(true 时 selection 列显示为单选框,只能选中一行) Boolean true / false false
disableCopy 是否禁止表格内容复制(true 时表格内容不可选中复制) Boolean true / false false

说明:开启 toolbar 后,表格顶部会显示工具栏区域,右侧有列设置按钮,点击打开列设置面板。面板中用户可以:

  • 勾选/取消勾选列名来控制列显隐
  • 点击对齐按钮设置左对齐/居中/右对齐
  • 点击固定按钮设置左固定/右固定/取消固定
  • 拖拽或点击上下移按钮调整列顺序
  • selectionindex 类型列不在面板中显示
  • 可通过 #toolbar 插槽在工具栏左侧放置自定义内容

Table 事件

事件名 说明 回调参数
自定义事件名 操作按钮点击事件,取决于 column renders 中 func 的参数名 (row, index)
sort-change 自定义排序时触发(column.sorter='custom') (column, 'asc'/'desc', columnIndex)
currentChange 当前行变化时触发,需开启 highlight (row, index)
toggleAllSelection 全选复选框变化 (selected, selectedArray)
toggleRowSelection 单行复选框变化 (selected, selectedArray)
getSelection 调用 getSelection() 方法时触发,返回当前选中行数组 (selectedArray)
rowClick 单击某行 (row, index)
cellClick 单击单元格 (row, index, column)
pullUpLoading 上拉加载触发(传统模式) 无参数
expand-change 树节点展开/折叠时触发 (row, expanded)
update:currentPage 分页当前页同步事件(支持 .sync 修饰符) page
pageChange 分页页码变化时触发 { currentPage, pageSize }
pageSizeChange 分页每页条数变化时触发 { currentPage, pageSize }
column-change 工具栏中列配置变化时触发(显隐/对齐/固定/排序) { type: 'visible'|'align'|'fixed'|'order', column, value }

Table 方法(通过 ref 调用)

方法名 说明 参数
pullUpCompleteLoading 结束上拉加载状态 type:空字符串代表还有数据,'ok' 代表结束
setLazyLoadStatus 手动设置懒加载状态 status'idle' / 'loading' / 'noMore' / 'error'
retryLazyLoad 懒加载错误时点击重试
resetHighlight 清除高亮行选中状态
clearSelection 清除所有复选框选中
getSelection 获取当前选中的行数据数组,同时触发 getSelection 事件
changePage 切换到指定页(分页模式) page:页码
onPageSizeChange 切换每页条数(分页模式) size:每页条数
toggleToolbarPanel 切换工具栏列设置面板显隐
closeToolbarPanel 关闭工具栏列设置面板
toggleColumnVisible 切换列的显隐状态 col:叶子列配置对象
setColumnAlign 设置列对齐方式 col:列配置对象, align'left'/'center'/'right'
setColumnFixed 设置列固定方式 col:列配置对象, fixedtrue/'left'/'right'/false
moveColumnUp 上移列顺序 idx:列在面板中的索引
moveColumnDown 下移列顺序 idx:列在面板中的索引
toggleRowExpansion 切换树节点展开/折叠状态 row:行数据对象

Data 属性

参数 说明 类型 可选值 默认值
checked 是否被勾选(多选模式下初始选中) Boolean true / false
key 行唯一标识(组件内部自动生成,设置 rowKey 后基于 rowKey 字段值生成,否则使用数组索引) String / Number 自动生成

树形数据额外属性

参数 说明 类型 可选值 默认值
children 子节点数组(同步树形表格) Array
hasChildren 是否有子节点(异步懒加载,设为 true 才显示展开箭头) Boolean true / false

Column 属性

参数 说明 类型 可选值 默认值
name 数据字段名 String
label 列标题文本 String
width 列宽度 (px),未设置时默认 100,列宽不足容器宽度时自动分配剩余空间 Number 100
minWidth 列最小宽度 (px),列宽计算结果低于此值时自动修正为 minWidth Number
type 列类型 String selection / index / operation / img / slot 普通文本列
align 对齐方式 String left / center / right left
fixed 固定列 Boolean / String true'left' 为左固定,'right' 为右固定
sorter 排序 Boolean / String true(内置排序)/ 'custom'(自定义排序,触发 sort-change 事件) false
filters 值映射过滤器,对象格式 {1:'启用', 0:'停用'} 或数组格式 [{value:1, label:'启用'}, {value:0, label:'停用'}] Object / Array
emptyString 空值时显示的占位文本 String '--'
formatter 标记此列使用全局 formatter 函数格式化 Any
slot 插槽名称,用于自定义列渲染内容(微信小程序需同时设置 tableCell String
headerSlot 自定义表头插槽名称(可选,不设置则与 slot 同名) String
showtips 是否启用长按/双击显示完整内容提示浮层 Boolean true / false false
tipsTime showtips 提示浮层显示时长 (ms) Number 3000
renders 操作按钮配置(仅 type='operation') Array
children 子列配置(多级表头),格式同 columns Array
tableCell 微信小程序插槽名(替代 slot,因小程序不支持动态具名插槽,需与 slot 同时设置) String
hidden 是否隐藏该列(true 时该列不显示,可通过工具栏重新显示) Boolean true / false false

renders 配置项(type='operation' 时)

renders: [
  {
    name: '编辑',          // 按钮文字
    type: 'primary',      // 按钮类型:primary/warn/default/custom(custom 为纯文字链接样式)
    size: 'mini',         // 按钮大小:mini/medium/default
    func: 'edit',         // 点击事件名,父组件通过 @edit 接收
    class: ''             // 自定义 CSS class
  },
  {
    name: '删除',
    type: 'warn',
    func: 'dele'
  }
]

父组件接收事件:<zb-table @edit="onEdit" @dele="onDele" />


<!-- end Column 属性 -->

插槽

该组件采用动态插槽模式,插槽名称由 column.slot 属性指定,无需在组件上预先声明具名插槽。

注意:微信小程序不支持动态具名插槽,需在使用 slot 的同时设置 column.tableCell 属性作为小程序插槽名。其他平台仅需 slot 即可。

插槽名 说明 作用域变量
[动态,由 column.slot 指定] 自定义列内容渲染(表体) { row, column, index }
[由 column.headerSlot 或 column.slot 指定] 自定义表头列渲染(表头),需设置 headerSlot { row: column, column: column, index }
toolbar 工具栏左侧自定义内容(需开启 toolbar 属性)

作用域变量说明

变量 说明
row 当前行数据对象(表头插槽中为列配置对象)
column 当前列配置对象
index 行索引,从 0 开始(表头插槽中为 column.leafStartIndex

表头列插槽

column.slot 有值时,表体列和表头列均可使用同名插槽进行自定义渲染。如需表头与表体使用不同插槽名,可通过 column.headerSlot 单独指定表头插槽名(未设置时默认与 slot 同名)。表头插槽作用域中 row 指向列配置对象,index 指向列的叶子起始索引。

示例:

<zb-table :columns="columns" :data="data">
  <!-- 表体插槽,自定义列内容 -->
  <template #statusSlot="{ row, column, index }">
    <text :style="{ color: row.status === 1 ? 'green' : 'red' }">
      {{ row.status === 1 ? '在线' : '离线' }}
    </text>
  </template>

  <!-- 表头插槽,通过 headerSlot 指定不同插槽名 -->
  <template #statusHeader="{ row: column }">
    <view class="custom-header">{{ column.label }}<text class="badge">NEW</text></view>
  </template>
</zb-table>
columns: [
  { name: 'status', label: '状态', slot: 'statusSlot', headerSlot: 'statusHeader' }
]

注意:如果仅需要自定义表体列内容,直接使用 column.slot 指定插槽名即可。表头插槽为可选扩展,仅在需要自定义表头时使用。


<!-- end 插槽 -->

使用示例

基础表格

<zb-table
  :columns="columns"
  :data="data"
  :stripe="true"
  :border="true"
  :fit="false"
  show-summary
  sum-text="合计"
  :summary-method="getSummaries"
  @toggleRowSelection="toggleRowSelection"
  @toggleAllSelection="toggleAllSelection"
  @rowClick="rowClick"
  @edit="buttonEdit"
  @dele="dele"
></zb-table>

树形表格(同步数据)

<zb-table
  ref="zbTable"
  :columns="treeColumns"
  :data="treeData"
  :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
  tree-column-name="name"
  :default-expand-all="false"
  :indent="20"
  row-key="id"
  @expand-change="onExpandChange"
></zb-table>
treeColumns: [
  { name: 'name', label: '名称' },         // treeColumnName='name' 指定此列展示树形缩进和展开图标
  { name: 'count', label: '人数', width: 80 },
  { name: 'operation', type: 'operation', label: '操作', width: 150, renders: [
    { name: '编辑', func: 'edit' }
  ]}
],
treeData: [
  { id: 1, name: '部门A', count: 20, children: [
    { id: 11, name: '小组1', count: 8 },
    { id: 12, name: '小组2', count: 12 }
  ]}
],
methods: {
  onExpandChange(row, expanded) {
    console.log(row.name, expanded ? '展开' : '折叠')
  },
  // 手动切换某行的展开/折叠
  toggleNode(row) {
    this.$refs.zbTable.toggleRowExpansion(row)
  }
}

说明treeColumnName 指定树形缩进和展开图标显示在哪一列。不设置时默认取第一个非 selection/index 类型的列。

树形表格(按层级展开)

使用 defaultExpandLevel 控制初始展开的层级数,比 defaultExpandAll 更灵活。

<zb-table
  :columns="treeColumns"
  :data="treeData"
  :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
  :default-expand-level="1"
  :indent="20"
  row-key="id"
></zb-table>
// defaultExpandLevel=1:只展开根节点(第一层),子节点默认折叠
// defaultExpandLevel=2:展开前两层,依此类推
// defaultExpandLevel=0:不展开任何节点(默认行为)

treeData: [
  { id: 1, name: '总部', children: [
    { id: 11, name: '部门A', children: [
      { id: 111, name: '小组1' },
      { id: 112, name: '小组2' }
    ]},
    { id: 12, name: '部门B', children: [
      { id: 121, name: '小组3' }
    ]}
  ]}
]

说明defaultExpandAlldefaultExpandLevel 同时存在时,defaultExpandAll 优先。两者仅对同步数据有效,异步懒加载需通过 treeLoad 动态加载后展开。

树形表格(异步懒加载)

<zb-table
  :columns="treeColumns"
  :data="treeData"
  :tree-props="{ hasChildren: 'hasChildren' }"
  :tree-load="loadTreeChildren"
  row-key="id"
></zb-table>
// 只有 hasChildren: true 的行才显示展开箭头并触发懒加载
treeData: [
  { id: 1, name: '部门A', hasChildren: true }  // 显示展开箭头
  { id: 2, name: '部门B' }                       // 叶子节点,无箭头
],
methods: {
  loadTreeChildren(row, resolve) {
    // 异步请求子节点数据
    setTimeout(() => {
      resolve([
        { id: row.id * 10 + 1, name: '子节点1' },
        { id: row.id * 10 + 2, name: '子节点2' }
      ])
    }, 500)
  }
}

分页模式

<zb-table
  :columns="columns"
  :data="data"
  :pagination="true"
  :current-page.sync="currentPage"
  :page-size="pageSize"
  :total="total"
  :show-page-size-changer="true"
  :show-quick-jumper="true"
  @pageChange="onPageChange"
  @pageSizeChange="onPageSizeChange"
></zb-table>

懒加载状态机

<zb-table
  :columns="columns"
  :data="data"
  :lazy-load="true"
  :lazy-load-text="{ loading: '加载中...', noMore: '没有更多了', error: '加载失败,点击重试' }"
  :lazy-load-threshold="40"
  @pullUpLoading="onLoadMore"
></zb-table>

插槽自定义列

<zb-table :columns="columns" :data="data">
  <template #statusSlot="{ row, column, index }">
    <text :style="{ color: row.status === 1 ? 'green' : 'red' }">
      {{ row.status === 1 ? '在线' : '离线' }}
    </text>
  </template>
</zb-table>
columns: [
  { name: 'status', label: '状态', slot: 'statusSlot' }
]

列宽拖拽调整

<zb-table
  :columns="columns"
  :data="data"
  :resizable="true"
  :resize-min-width="50"
></zb-table>

单元格提示浮层

columns: [
  { name: 'description', label: '描述', width: 120, showtips: true, tipsTime: 3000 }
]

长按或双击该列单元格时,会在触摸位置弹出完整内容提示浮层,自动消失。

H5 横向滚动条

H5 端在表格底部提供自定义横向滚动条,支持鼠标拖拽滑块、点击轨道跳转,移动端支持触摸拖动。默认 "auto" 模式:PC 端(窗口宽度 > 720px)显示,移动端自动隐藏使用原生滑动。

<!-- 默认自动模式:PC端显示,移动端隐藏 -->
<zb-table :columns="columns" :data="data"></zb-table>

<!-- 移动端也强制显示 -->
<zb-table :columns="columns" :data="data" :show-h-scrollbar="true"></zb-table>

<!-- 始终隐藏 -->
<zb-table :columns="columns" :data="data" :show-h-scrollbar="false"></zb-table>

交互说明:滑块宽度反映内容与可视区域的比例。拖拽滑块或点击轨道,表头、表体、合计行同步横向滚动,左/右固定列不受影响。

多级表头

通过 column 的 children 属性配置嵌套列,实现多级表头。子列会继承父列的 fixedalign 属性(子列未设置时)。

columns: [
  { name: 'name', label: '姓名', width: 80 },
  {
    label: '基本信息',
    children: [
      { name: 'age', label: '年龄', width: 80, align: 'center' },
      { name: 'sex', label: '性别', width: 80, filters: { 0: '男', 1: '女' } }
    ]
  },
  {
    label: '地址信息',
    children: [
      { name: 'province', label: '省份', width: 100 },
      { name: 'city', label: '城市', width: 100 },
      { name: 'address', label: '详细地址', width: 200 }
    ]
  },
  { name: 'operation', type: 'operation', label: '操作', width: 150, renders: [
    { name: '编辑', func: 'edit' },
    { name: '删除', type: 'warn', func: 'dele' }
  ]}
]

说明:多级表头中,只有叶子列(最底层的列)会渲染数据单元格,父列只渲染表头合并单元格。表头行高 = 表头行数 × headerRowHeight

右固定列

通过设置 fixed: 'right' 实现右侧固定列,常用于操作按钮列。

columns: [
  { name: 'name', label: '姓名', width: 80 },
  { name: 'age', label: '年龄', width: 80 },
  { name: 'address', label: '地址' },
  { name: 'date', label: '日期', width: 120 },
  // 右固定操作列
  { name: 'operation', type: 'operation', label: '操作', fixed: 'right', width: 150, renders: [
    { name: '编辑', func: 'edit' },
    { name: '删除', type: 'warn', func: 'dele' }
  ]}
]

说明:右固定列仅在内容宽度超出容器时才会显示为固定面板,内容未超出时与普通列一致,避免重复显示。左固定列同理。

序号列

设置 type: 'index' 即可自动显示从 1 开始的行号。

columns: [
  { type: 'index', label: '序号', width: 60, align: 'center' },
  { name: 'name', label: '姓名', width: 80 },
  { name: 'age', label: '年龄', width: 80 }
]

图片列

设置 type: 'img' 显示图片,支持单张(字符串)和多张(数组),点击可预览大图。

columns: [
  { name: 'avatar', label: '头像', type: 'img', width: 80 },
  { name: 'photos', label: '相册', type: 'img', width: 160 }
]

// 数据格式
data: [
  { avatar: 'https://example.com/img1.jpg', photos: ['https://example.com/p1.jpg', 'https://example.com/p2.jpg'] },
  { avatar: '', photos: '' }  // 空值显示 emptyString
]

全局格式化(formatter)

通过 formatter prop 定义全局格式化函数,在列配置中设置 formatter: true 启用。

<zb-table
  :columns="columns"
  :data="data"
  :formatter="globalFormatter"
></zb-table>
columns: [
  { name: 'name', label: '姓名' },
  { name: 'salary', label: '薪资', formatter: true },  // 启用全局格式化
  { name: 'date', label: '日期' }
],
methods: {
  globalFormatter(row, column, rowIndex, columnIndex) {
    if (column.name === 'salary') {
      return '¥' + Number(row.salary).toLocaleString()
    }
    return row[column.name]
  }
}

值映射过滤器(filters)

使用 filters 将数据值映射为显示文本,无需手动转换数据。

// 对象格式:键为数据值,值为显示文本
{ name: 'status', label: '状态', filters: { 0: '停用', 1: '启用' } }

// 数组格式:适用于键为非字符串类型
{ name: 'type', label: '类型', filters: [
  { value: 1, label: '类型A' },
  { value: 2, label: '类型B' },
  { value: 3, label: '类型C' }
]}

自定义单元格样式

通过 cellStylecellHeaderStyle 动态设置单元格样式。

<zb-table
  :columns="columns"
  :data="data"
  :cell-style="cellStyle"
  :cell-header-style="headerStyle"
></zb-table>
methods: {
  // 数据行单元格样式
  cellStyle({ row, column, rowIndex, columnIndex }) {
    if (column.name === 'status' && row.status === 0) {
      return { color: '#f56c6c', fontWeight: 'bold' }
    }
    return {}
  },
  // 表头单元格样式
  headerStyle({ column, columnIndex }) {
    if (column.name === 'salary') {
      return { color: '#e6a23c' }
    }
    return {}
  }
}

动态操作按钮权限

通过 permissionBtn 根据行数据动态控制操作按钮的显示隐藏。

<zb-table
  :columns="columns"
  :data="data"
  :permission-btn="filterButtons"
  @edit="onEdit"
  @delete="onDelete"
></zb-table>
columns: [
  { name: 'name', label: '姓名' },
  { name: 'operation', type: 'operation', label: '操作', renders: [
    { name: '编辑', func: 'edit' },
    { name: '删除', type: 'warn', func: 'delete' },
    { name: '查看', type: 'custom', func: 'view' }
  ]}
],
methods: {
  // 返回需要显示的按钮数组
  filterButtons(row, renders, index) {
    if (row.disabled) {
      return renders.filter(r => r.func !== 'delete')  // 禁用行不显示删除按钮
    }
    return renders
  }
}

自定义合计行

通过 summaryMethod 自定义合计行的计算逻辑。

<zb-table
  :columns="columns"
  :data="data"
  show-summary
  sum-text="合计"
  :summary-method="getSummaries"
></zb-table>
methods: {
  getSummaries({ columns, data }) {
    const sums = []
    columns.forEach((column, index) => {
      if (index === 0) {
        sums[index] = '总计'
        return
      }
      if (column.name === 'salary') {
        const values = data.map(item => Number(item[column.name]))
        sums[index] = values.reduce((prev, curr) => prev + curr, 0).toLocaleString()
      } else {
        sums[index] = '--'
      }
    })
    return sums
  }
}

微信小程序插槽

微信小程序不支持动态具名插槽,需同时设置 slottableCell 属性。

<!-- 非微信小程序平台 -->
<zb-table :columns="columns" :data="data">
  <template #statusSlot="{ row, column, index }">
    <text :style="{ color: row.status === 1 ? 'green' : 'red' }">
      {{ row.status === 1 ? '在线' : '离线' }}
    </text>
  </template>
</zb-table>

<!-- 微信小程序平台 -->
<zb-table :columns="columns" :data="data">
  <template #tableCell="{ row, column, index }">
    <view v-if="column.name === 'status'">
      <text :style="{ color: row.status === 1 ? 'green' : 'red' }">
        {{ row.status === 1 ? '在线' : '离线' }}
      </text>
    </view>
  </template>
</zb-table>
// 非微信小程序
columns: [
  { name: 'status', label: '状态', slot: 'statusSlot' }
]

// 微信小程序(需同时设置 slot 和 tableCell)
columns: [
  { name: 'status', label: '状态', slot: 'statusSlot', tableCell: 'tableCell' }
]

列宽自适应与自动分配

<!-- fit 模式:根据内容自动计算列宽 -->
<zb-table :columns="columns" :data="data" :fit="true"></zb-table>

<!-- 非fit模式:未设置width的列默认100px,列宽总和不足容器时自动平均分配剩余空间 -->
<zb-table :columns="columns" :data="data"></zb-table>

行为说明

  • fit=true 时,列宽根据表头文字和数据内容自动计算,用户拖拽过的列不会再次自动适配
  • fit=false(默认)时,未设置 width 的列默认 100px;当所有列宽总和小于容器宽度时,剩余空间会平均分配给未显式设置 width 的列
  • 用户手动拖拽调整过的列(_userResized)不会被自动分配覆盖
  • 可通过 minWidth 设置列的最小宽度,避免列被压缩过小

多选 Checkbox

设置 type: 'selection' 列即可启用多选功能,支持单选、全选、初始选中、获取选中数据。

<zb-table
  ref="zbTable"
  :columns="columns"
  :data="data"
  row-key="id"
  @toggleRowSelection="onRowSelect"
  @toggleAllSelection="onAllSelect"
></zb-table>
columns: [
  { type: 'selection', fixed: true, width: 50 },
  { name: 'name', label: '姓名', width: 80 },
  { name: 'age', label: '年龄', width: 80 }
],
data: [
  { id: 1, name: '张三', age: 25, checked: true },   // checked: true 初始选中
  { id: 2, name: '李四', age: 30 },
  { id: 3, name: '王五', age: 28, checked: true }
],
methods: {
  // 单行选中变化
  onRowSelect(selected, selectedArray) {
    console.log('当前选中状态:', selected)
    console.log('已选中行:', selectedArray)
  },
  // 全选变化
  onAllSelect(selected, selectedArray) {
    console.log('全选状态:', selected)
    console.log('已选中行:', selectedArray)
  },
  // 主动获取选中行
  getSelected() {
    const selected = this.$refs.zbTable.getSelection()
    console.log('当前选中行:', selected)
  },
  // 清除所有选中
  clearSelected() {
    this.$refs.zbTable.clearSelection()
  }
}

行高亮

设置 highlight 启用行高亮,点击行时高亮显示并触发 currentChange 事件。

<zb-table
  :columns="columns"
  :data="data"
  :highlight="true"
  row-key="id"
  @currentChange="onCurrentChange"
></zb-table>
methods: {
  onCurrentChange(row, index) {
    console.log('选中行:', row)
    console.log('行索引:', index)
  },
  // 手动清除高亮
  clearHighlight() {
    this.$refs.zbTable.resetHighlight()
  }
}

说明:高亮行背景色为 #ecf5ff,可通过 CSS 覆盖 .current-row .item-td 样式自定义。

自定义排序

设置 sorter: 'custom' 启用自定义排序,排序时触发 sort-change 事件,由业务方自行处理数据排序。

<zb-table
  :columns="columns"
  :data="data"
  @sort-change="onSortChange"
></zb-table>
columns: [
  { name: 'name', label: '姓名' },
  { name: 'salary', label: '薪资', sorter: 'custom' },  // 自定义排序
  { name: 'joinDate', label: '入职日期', sorter: 'custom' }
],
methods: {
  onSortChange(column, order, columnIndex) {
    // column: 列配置对象
    // order: 'asc' 或 'desc'
    // columnIndex: 列索引
    console.log(`按 ${column.name} 列 ${order} 排序`)

    // 自行请求后端排序接口或前端排序
    this.loadData({ sortField: column.name, sortOrder: order })
  }
}

说明sorter: true(内置排序)由组件内部完成排序,支持数值、日期、中文自然排序(如 "DF-5C" 正确识别数字部分)。sorter: 'custom' 适用于服务端排序场景。

组合场景:多选 + 分页

多选与分页组合使用时,建议设置 rowKey 以保持跨页选中状态稳定。

<zb-table
  ref="zbTable"
  :columns="columns"
  :data="pageData"
  row-key="id"
  :pagination="true"
  :current-page.sync="currentPage"
  :page-size="pageSize"
  :total="total"
  @toggleRowSelection="onRowSelect"
  @pageChange="onPageChange"
></zb-table>
columns: [
  { type: 'selection', fixed: true, width: 50 },
  { name: 'name', label: '姓名' },
  { name: 'age', label: '年龄' }
],
methods: {
  onPageChange({ currentPage, pageSize }) {
    this.currentPage = currentPage
    this.fetchData(currentPage, pageSize)
  },
  onRowSelect(selected, selectedArray) {
    // 跨页选中状态通过 rowKey 保持
    this.selectedRows = selectedArray
  }
}

组合场景:左固定 + 右固定 + 多级表头

同时使用左右固定列和多级表头的完整示例。

columns: [
  { type: 'selection', fixed: true, width: 50 },
  { name: 'name', label: '姓名', fixed: true, width: 80 },
  {
    label: '基本信息',
    children: [
      { name: 'age', label: '年龄', width: 80 },
      { name: 'sex', label: '性别', width: 80, filters: { 0: '男', 1: '女' } }
    ]
  },
  {
    label: '地址信息',
    children: [
      { name: 'province', label: '省份', width: 100 },
      { name: 'city', label: '城市', width: 100 }
    ]
  },
  { name: 'date', label: '日期', width: 120, sorter: true },
  // 右固定操作列
  { name: 'operation', type: 'operation', label: '操作', fixed: 'right', width: 150, renders: [
    { name: '编辑', func: 'edit' },
    { name: '删除', type: 'warn', func: 'dele' }
  ]}
]

说明:父列设置 fixed 时,子列会自动继承。多级表头中固定列的判定以叶子列为准。

工具栏(列设置面板)

设置 toolbar 属性后,表格顶部会出现工具栏,用户可通过列设置面板动态调整列的显隐、对齐方式、固定方式和排列顺序。

<zb-table
  :columns="columns"
  :data="data"
  :toolbar="true"
  @column-change="onColumnChange"
>
  <!-- 工具栏左侧可放置自定义内容 -->
  <template #toolbar>
    <text class="toolbar-title">数据列表</text>
  </template>
</zb-table>
methods: {
  onColumnChange({ type, column, value }) {
    // type: 'visible' | 'align' | 'fixed' | 'order'
    // column: 变化的列配置对象
    // value: 变化后的值
    console.log(`列 ${column.name} 的 ${type} 变为 ${value}`)

    // 可在此持久化用户列配置(如存入 localStorage)
    if (type === 'visible') {
      console.log(column.name, value ? '显示' : '隐藏')
    } else if (type === 'align') {
      console.log(column.name, '对齐方式', value)
    } else if (type === 'fixed') {
      console.log(column.name, '固定方式', value)
    } else if (type === 'order') {
      console.log(column.name, '移动到位置', value)
    }
  }
}

工具栏面板功能

  • 列显隐:点击列名前的复选框切换显隐
  • 对齐方式:左对齐/居中/右对齐
  • 固定方式:左固定/右固定/取消固定
  • 列排序:拖拽排列或点击上移/下移按钮调整列顺序
  • selectionindex 类型列不在面板中显示
  • 设置了 hidden: true 的列在面板中默认为未选中状态,可通过面板重新显示

单选模式

设置 singleSelect 后,selection 列显示为单选框,同一时间只能选中一行。

<zb-table
  :columns="columns"
  :data="data"
  :single-select="true"
  row-key="id"
  @toggleRowSelection=""
></zb-table>
columns: [
  { type: 'selection', width: 50 },
  { name: 'name', label: '姓名' },
  { name: 'age', label: '年龄' }
],
methods: {
  (selected, selectedArray) {
    // selected: Boolean(当前行是否选中)
    // selectedArray: 选中行数组(单选模式下最多1个元素)
    console.log('选中行:', selectedArray)
  }
}

说明singleSelect=true 时,全选复选框不显示,点击某行单选框会自动取消之前选中的行。

禁止内容复制

设置 disableCopy 后,表格内容不可被鼠标选中复制,适用于数据安全场景。

<zb-table
  :columns="columns"
  :data="data"
  :disable-copy="true"
></zb-table>

自定义行样式

通过 rowStyle 设置整行样式,优先级低于 cellStyle

<zb-table
  :columns="columns"
  :data="data"
  :row-style="rowStyle"
></zb-table>
methods: {
  rowStyle({ row, rowIndex }) {
    if (row.expired) {
      return { backgroundColor: '#fef0f0', color: '#f56c6c' }
    }
    if (rowIndex % 2 === 0) {
      return { backgroundColor: '#f0f9ff' }
    }
    return {}
  }
}

隐藏列

设置 hidden: true 可初始隐藏列,后续可通过工具栏面板重新显示。

columns: [
  { name: 'name', label: '姓名' },
  { name: 'age', label: '年龄' },
  { name: 'salary', label: '薪资', hidden: true },   // 初始隐藏
  { name: 'address', label: '地址' }
]

说明hidden 为列的初始状态,配合 toolbar 使用时用户可在面板中重新勾选显示。


注意事项

  1. rowKey 推荐设置:树形表格和多选模式下,强烈建议设置 rowKey(如 "id"),以确保行唯一标识稳定。未设置时使用数组索引,数据增删后可能导致选中状态异常。

  2. 列宽计算:组件内部统一使用 transColumns 作为列宽数据源,表头、表体、合计行宽度保持一致。未设置 width 的列默认 100px。

  3. 列宽拖拽与自动分配:用户手动拖拽调整过的列宽会被标记(_userResized),不会被后续的自动平均分配覆盖。如需重置,修改 columns 的 width 值即可。

  4. 微信小程序插槽限制:微信小程序不支持动态具名插槽,必须同时设置 slottableCell 属性,且插槽名固定为 tableCell,在插槽内通过 column.name 判断当前列。

  5. 树形异步懒加载:只有数据项显式包含 hasChildren: true 才会显示展开箭头并触发 treeLoad,否则视为叶子节点。treeLoad 函数中需调用 resolve(childrenArray) 完成加载。

  6. 排序模式sorter: true 为内置排序(支持数值/日期/中文自然排序),sorter: 'custom' 为自定义排序(触发 sort-change 事件,需自行处理数据排序)。

  7. 固定列显示条件:左/右固定列面板仅在内容宽度超出容器时才会启用,内容未超出时固定列与普通列一致显示,避免重复。

  8. 数据响应式:修改 datacolumns 后组件会自动更新。小程序端可能需要 $forceUpdate 辅助刷新,组件内部已处理。

  9. 图片列type: 'img' 的列支持字符串(单图)和数组(多图)格式,点击图片会调用 uni.previewImage 预览。

  10. 上拉加载 vs 懒加载状态机:推荐使用 lazyLoad 懒加载状态机替代传统 isShowLoadMore,状态机提供 loading/noMore/error 三种状态,交互体验更好。

  11. pullUpLoading prop 与事件pullUpLoading 既是 prop(Function 类型,传入回调函数)也是事件(通过 @pullUpLoading 监听)。使用 prop 方式可调用 done() 控制加载状态;使用事件方式需手动调用 this.$refs.zbTable.pullUpCompleteLoading('ok') 结束加载。

  12. sorter: false 的行为sorter 默认为 false,表示该列不显示排序图标。设置为 true 显示排序图标并由组件内部排序,设置为 'custom' 显示排序图标但由业务方处理排序逻辑。

  13. 多级表头中固定列的继承:父列设置 fixed 时,其子列会自动继承 fixedalign 属性(子列未显式设置时)。多级表头中固定列的判定以叶子列为准。

  14. columns 不可变约定:组件内部会对 columns 进行深克隆处理,不会修改原始 props。但直接修改 columns 数组引用(如 this.columns = newColumns)才会触发组件重新计算,修改数组内部对象的属性需使用 this.$set

  15. 工具栏列配置持久化:工具栏中的列显隐、对齐、固定、排序等操作仅在当前会话生效。如需持久化用户列配置,监听 column-change 事件并将配置存入 localStorage,初始化时从 localStorage 恢复 columns 配置即可。

  16. 单选模式singleSelect=true 时,全选复选框不显示,点击任意行单选框会自动取消之前选中的行。toggleRowSelection 事件回调中 selectedArray 最多包含 1 个元素。

  17. 隐藏列column.hidden=true 为初始隐藏状态,不影响数据渲染逻辑,仅控制列是否在表头和表体中可见。配合 toolbar 使用时用户可在列设置面板中重新勾选显示。


兼容平台

平台 支持情况
H5(PC 浏览器) Chrome / IE / Edge / Firefox / Safari ✅
H5(移动浏览器) Safari / Android Browser / 微信浏览器 / QQ浏览器 ✅
App (Vue)
App (nVue) ⚠️ 部分支持
微信小程序
阿里小程序
百度小程序
字节跳动小程序
QQ 小程序
快应用(华为/联盟)

更新日志

详见 changelog.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。