vxe-table 进阶:同时使用 formatter 与 cell-render 实现格式化与样式定制

在开发表格组件时,我们经常需要完成两个任务:格式化原始数据(如数字千分位、日期格式化)和自定义单元格样式(如根据数值显示不同颜色、添加后缀)。

vxe-table 提供了 formatter 和 cell-render 两个配置项,二者可以组合使用,让数据逻辑与展示样式分离,达到更灵活的配置效果。

本文通过一个金额列的示例,演示如何同时使用 formatter 对数字添加千分位分隔符,再通过自定义渲染器 cell-render 将格式化后的内容渲染为红色并加上"元"后缀。

效果预览

  • 金额列会显示为:
    • 原始数据:1000 → 展示 1,000元(红色)
    • 原始数据:254400000 → 展示 254,400,000元(红色)

代码

定义渲染器

1.1 首先需要使用 VxeUI.renderer.add 注册一个渲染器,渲染器内部引用一个 Vue 组件(DemoCellStyle.vue),该组件负责最终单元格的样式呈现。

注册渲染器 (renderer.js)

javascript 复制代码
import { VxeUI } from 'vxe-pc-ui'

import DemoCellStyle from './DemoCellStyle.vue'

// 创建单元格样式渲染器
VxeUI.renderer.add('MyTableCellStyle', {
  // 默认显示模板
  renderTableDefault(renderOpts, renderParams) {
    return <DemoCellStyle render-params={renderParams} />
  }
})

2.1 编写渲染器组件 DemoCellStyle.vue

该组件通过 renderParams 获取当前单元格的上下文,并调用 $table.getCellLabel(row, column) 来获取 经过 formatter 处理后的文本内容,然后将其包裹在自定义样式中。

html 复制代码
<template>
  <span style="color: red">{{ cellLabel }}元</span>
</template>

<script setup>
import { ref, computed } from 'vue'

const props = defineProps({
  renderParams: {
    type: Object,
    default: () => ({})
  }
})

const cellLabel = computed(() => {
  const { renderParams } = props
  const { $table, row, column } = renderParams
  if ($table && row && column) {
    return $table.getCellLabel(row, column)
  }
  return ''
})
</script>
  • 关键点:$table.getCellLabel() 会优先执行列上配置的 formatter 函数,拿到格式化后的字符串,然后传给自定义渲染器。这样我们就实现了 formatter 负责数据格式化,cell-render 负责样式展示 的完美分工。

使用

  • 在 vxe-grid 的列定义中:
    • formatter:对原始数值添加千分位分隔符(例如 1000 → 1,000)。
    • cellRender:指定使用上面注册的渲染器 'MyTableCellStyle',该渲染器会将格式化后的文本加上"元"后缀并显示为红色。
html 复制代码
<template>
  <div>
    <vxe-grid v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script lang="jsx" setup>
import { reactive } from 'vue'
import XEUtils from 'xe-utils'
const gridOptions = reactive({
  border: true,
  height: 300,
  columns: [
    { type: 'seq', width: 50 },
    { field: 'name', title: 'Name' },
    { field: 'sex', title: 'Sex' },
    {
      field: 'amount',
      title: 'Amount',
      // 数据格式化:千分位分隔
      formatter({ cellValue }) {
        return XEUtils.commafy(cellValue)
      },
      // 式渲染:使用自定义渲染器
      cellRender: {
        name: 'MyTableCellStyle'
      }
    }
  ],
  data: [
    { id: 10001, name: 'Test1', sex: 'Man', age: 28, amount: 1000 },
    { id: 10002, name: 'Test2', sex: 'Women', age: 22, amount: 254400000 },
    { id: 10003, name: 'Test3', sex: 'Man', age: 32, amount: 999954 },
    { id: 10004, name: 'Test4', sex: 'Women', age: 23, amount: 10000000 }
  ]
})
</script>

原理说明

配置项 职责 执行顺序
formatter 将原始数据转换为展示用的纯文本(如数字千分位、日期格式化) 先执行
cellRender 接管整个单元格的渲染,可自定义任意 VNode 或组件 后执行,并可获取 formatter 的结果

两者组合时,cellRender 内部通过 $table.getCellLabel(row, column) 拿到已经经过 formatter 处理的文本,然后进行二次包装(加后缀、改颜色、加图标等)。这样既复用了 formatter 的格式化能力,又保留了渲染器的高度灵活性。

说明

  • cellRender 会完全接管单元格内容:一旦配置了 cellRender,默认的文本渲染就会被覆盖,所以必须在自定义组件内显式调用 getCellLabel 来呈现格式化后的文本。
  • 性能考虑:如果只是简单的样式修改(如颜色、字体),也可以直接使用 cellClassName 或 style 回调;但当需要组合复杂逻辑(如根据多列值、动态添加组件)时,cellRender 更加强大。
  • 扩展性:通过注册不同的渲染器,可以在不同列或不同项目中复用样式逻辑。

这种模式非常适合需要统一格式化数据,但又希望在不同场景下呈现不同样式的业务需求(如金额、状态标签、进度条等)。

https://vxetable.cn

相关推荐
程序员Sunday4 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
Setsuna_F_Seiei5 小时前
前端转型 Agent 开发 06 之 Agent Memory 记忆系统(让 Agent 更智能,更懂你)
前端·agent·ai编程
志尊宝5 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
zhangzeyuaaa5 小时前
Ruby 多线程、GVL(GIL)与 Mutex 完全指南
开发语言·前端·ruby
默_笙6 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
优选资讯6 小时前
标签打印软件怎么对接 Excel 数据
前端·excel
思无邪667 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
一个风轻云淡7 小时前
GCC 和 GDB命令简单解读
java·linux·前端
u0111026758 小时前
图片处理接口如何统一错误信息 前端提示与后端错误码设计
前端·状态模式
福兮说8 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic