尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Handsontable 单元格格式化指南:className、renderer 与 customBorders 的完整实战

Handsontable 单元格格式化指南:className、renderer 与 customBorders 的完整实战 Handsontable 单元格格式化指南className、renderer 与 customBorders 的完整实战【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable导读Handsontable 底层渲染的是一张原生 HTMLtable因此你可以像操作普通表格一样通过 CSS 类、内联样式或边框定义来改变单元格外观。本指南以 formatting-cells.md 为核心骨架围绕className、renderer与customBorders三种方式结合仓库中的示例代码与 CustomBorders 插件源码完整讲解从给单元格加类到为大规模配置渐进式绘制边框的实操方法与底层原理。读完你将为任意单元格、行列或选中区域实现静态样式、动态内联样式与自定义边框。三种格式化方式的选型Handsontable 渲染一个 HTMLtable所以你既可以给已有的tr、td元素写 CSS也可以挂载自己的类名。根据目标选择合适的方式目标推荐方式适用场景可复用的静态样式className整表、整行、整列或特定单元格挂固定类名由 CSS 规则统一定义外观渲染时按数据动态设置样式renderer需要根据单元格的值、状态在每次渲染时动态写入内联样式自定义边框宽度、颜色与样式customBorders对选中的单元格范围应用实线、虚线、点线等边框效果前提条件一个已加载数据的 Handsontable 实例本文示例数据为商品清单SKU、产品名、分类、价格、库存。一张样式表如果你要通过自定义 CSS 类来格式化单元格。使用自定义 CSS 类className通过className选项可以为单元格、列或行添加 CSS 类。它可以在三个层级设置网格配置中类名会同时添加到承载表格的容器元素以及单元格的td上columns条目中作用于对应列的每个单元格cells回调中按单元格逐格控制也可以使用cell数组按坐标声明。下面这个示例给左上角单元格添加custom-cell类并给整个网格添加custom-table类以高亮表头。完整源码见 example1.js、example1.ts 与 example1.cssimport Handsontable from handsontable/base; import { registerAllModules } from handsontable/registry; // Register all Handsontables modules. registerAllModules(); const container document.querySelector(#example1); new Handsontable(container, { data: [ [SKU-4821, Laptop Pro 15, Electronics, 149900, 42], [SKU-0093, Wireless Mouse, Peripherals, 2999, 218], [SKU-7712, USB-C Hub 7-port, Peripherals, 5499, 0], [SKU-3305, Mech. Keyboard, Peripherals, 8999, 67], [SKU-9140, 4K Monitor 27, Electronics, 34999, 15], ], rowHeaders: true, colHeaders: [SKU, Product, Category, Price ($), Stock], stretchH: all, className: custom-table, cell: [ { row: 0, col: 0, className: custom-cell, }, ], height: auto, autoWrapRow: true, autoWrapCol: true, licenseKey: non-commercial-and-evaluation, });对应的 CSS注意示例中使用了!important因为下面提高选择器优先级一节会解释主题规则的干扰td.custom-cell { color: #fff !important; background-color: #254ac6 !important; } .custom-table thead th:nth-child(even), .custom-table tbody tr:nth-child(odd) th { color: #fff !important; background-color: #254ac6 !important; }要点你提供的类名会被加到单元格的td元素上CSS 规则可以精确命中它设置在网格配置中时类名同时加到容纳网格的容器元素上完整的层级行为参见className选项文档该示例同样提供了 Reactexample1.jsx、example1.tsx、Angularexample1.ts、example1.html与 Vueexample1.vue版本各框架用法一致。给规则足够的优先级内置主题通过诸如.ht-theme-main .htCore td这样的规则来样式化单元格它比单个类选择器如.custom-cell更具体。因此一条形如.custom-cell { font-size: 24px; }的规则会输给主题单元格仍保持主题的字体大小。要取胜请在选择器中同时包含主题类与元素.ht-theme-main .htCore td.custom-cell { font-size: 24px; }给原规则加!important同样有效但上面的写法能让层叠关系保持清晰可读。另外autoRowSize与autoColumnSize在测量时会带上已应用的类所以一个改变字体大小、内边距或边框的类会被正确反映到计算出的行高与列宽中。使用内联样式自定义 renderer内联样式通过单元格 DOM 元素的style属性直接设置借助renderer选项在每次渲染时执行这段逻辑。下方示例定义了一个customStylesRenderer先调用内置的textRenderer完成默认文本渲染再覆盖TD的字体、颜色与背景。完整源码见 example2.js 与 example2.tsimport Handsontable from handsontable/base; import { registerAllModules } from handsontable/registry; import { textRenderer, registerRenderer } from handsontable/renderers; // Register all Handsontables modules. registerAllModules(); const customStylesRenderer (hotInstance, TD, ...rest) { textRenderer(hotInstance, TD, ...rest); TD.style.fontWeight bold; TD.style.color green; TD.style.background #d7f1e1; }; registerRenderer(customStylesRenderer, customStylesRenderer); const container document.querySelector(#example2); new Handsontable(container, { data: [ [SKU-4821, Laptop Pro 15, Electronics, 149900, 42], [SKU-0093, Wireless Mouse, Peripherals, 2999, 218], [SKU-7712, USB-C Hub 7-port, Peripherals, 5499, 0], [SKU-3305, Mech. Keyboard, Peripherals, 8999, 67], [SKU-9140, 4K Monitor 27, Electronics, 34999, 15], ], rowHeaders: true, colHeaders: [SKU, Product, Category, Price ($), Stock], stretchH: all, cell: [ { row: 0, col: 0, renderer: customStylesRenderer, }, ], height: auto, autoWrapRow: true, autoWrapCol: true, licenseKey: non-commercial-and-evaluation, });关键点renderer 的函数签名是(hotInstance, TD, ...rest)其中TD就是将要写入页面的单元格 DOM 元素直接修改它的style即可用registerRenderer(customStylesRenderer, customStylesRenderer)注册后即可在配置中以字符串renderer: customStylesRenderer引用由于渲染器在每次渲染时都会执行你可以在这里读取单元格数据通过...rest中传递的row、col、prop、value等参数实现条件化的动态样式——这也是实现条件格式化的底层机制。自定义单元格边框customBorders启用自定义边框只需设置customBorders设置为true为当前选中区域应用默认边框1px 黑色实线传入一个包含边框配置的数组按配置精确控制每一条边。在 API 属性名中start和end指的是 布局方向layout direction的起始边与结束边——在 LTR 布局中对应左/右在 RTL 布局中自动反转。边框样式通过边框配置中的style属性定制可选值如下源码中定义于 customBorders.ts 的SUPPORTED_STYLESsolid默认— 实线边框dashed— 虚线边框dotted— 点线边框style属性可以对任意边框边top、bottom、start、end单独设置未指定时默认为solid。此外每条边还支持width宽度与color颜色属性当某条边的配置为空对象时应用默认样式1px 黑色实线。下面的示例对两个区域应用了不同的边框样式完整源码见 example3.js 与 example3.tsimport Handsontable from handsontable/base; import { registerAllModules } from handsontable/registry; // Register all Handsontables modules. registerAllModules(); const container document.querySelector(#example3); new Handsontable(container, { data: [ [SKU-4821, Laptop Pro 15, Electronics, 149900, 42], [SKU-0093, Wireless Mouse, Peripherals, 2999, 218], [SKU-7712, USB-C Hub 7-port, Peripherals, 5499, 0], [SKU-3305, Mech. Keyboard, Peripherals, 8999, 67], [SKU-9140, 4K Monitor 27, Electronics, 34999, 15], ], rowHeaders: true, colHeaders: [SKU, Product, Category, Price ($), Stock], autoWrapRow: true, autoWrapCol: true, stretchH: all, height: auto, licenseKey: non-commercial-and-evaluation, customBorders: [ { // 矩形范围第 1~3 行、第 1~4 列 range: { from: { row: 1, col: 1 }, to: { row: 3, col: 4 }, }, top: { width: 2, color: #5292F7, style: dotted }, bottom: { width: 2, color: red }, // style 缺省 solid start: { width: 2, color: orange, style: dashed }, end: { width: 2, color: magenta }, // style 缺省 solid }, { // 单单元格第 2 行第 2 列 row: 2, col: 2, start: { width: 2, color: red }, end: { width: 1, color: green }, }, ], });配置结构要点范围边框用range: { from: {row, col}, to: {row, col} }描述矩形区域单格边框直接用rowcol定位每边独立top/bottom/start/end可分别设置width、color、style。除静态配置外CustomBorders 插件还提供编程式 APIsetBorders(selectionRanges, borderObject)为选区设置边框、getBorders(selectionRanges)读取边框配置、clearBorders(selectionRanges)清除边框不传选区则作用于当前选中区域详见 customBorders.ts 中的方法注释与示例。该插件也向右键菜单注入了上/下/左/右边框与无边框等上下文菜单项。大型配置的渐进式边框应用在首次渲染前构建一个非常大的customBorders配置会延迟首屏绘制。为了让网格先渲染出来、再在后台分批应用边框可以设置customBordersProgressive为trueconst hot new Handsontable(container, { data, customBorders: largeBorderConfig, customBordersProgressive: true, licenseKey: non-commercial-and-evaluation, });也可以传入对象来控制每批应用的边框条目数量customBordersProgressive: { chunkSize: 5000 },chunkSize的默认值是 5000定义于 customBorders.ts 的DEFAULT_PROGRESSIVE_CHUNK_SIZE每一批的规模被控制在单帧预算内避免阻塞交互。从源码实现看启用后插件会克隆边框配置并以chunkSize为粒度在后台逐批应用#startProgressiveApply见 customBorders.ts。启用渐进式应用后边框会在网格可交互之后陆续填充因此getBorders()以及单元格的边框元数据只有在afterCustomBordersUpdate钩子触发时才是完整的const hot new Handsontable(container, { data, customBorders: largeBorderConfig, customBordersProgressive: true, licenseKey: non-commercial-and-evaluation, afterCustomBordersUpdate() { // every custom border is now applied }, });该钩子适合用来做依赖全部边框已就绪的后续操作例如导出、截图或汇总统计。相关配置项与插件围绕单元格格式化Handsontable 还提供了一批开箱即用的类名配置项activeHeaderClassName当前活动表头单元格的类名className单元格/容器通用类名commentedCellClassName含批注单元格的类名currentColClassName当前列单元格的类名currentHeaderClassName当前表头单元格的类名currentRowClassName当前行单元格的类名customBorders自定义边框配置customBordersProgressive边框渐进式分批应用invalidCellClassName校验失败单元格的类名noWordWrapClassName禁止自动换行单元格的类名placeholder占位符文本配置placeholderCellClassName显示占位符单元格的类名readOnlyCellClassName只读单元格的类名tableClassName内部表格元素的类名相关插件为 CustomBorders源码位于 handsontable/src/plugins/customBorders。若你的需求是按单元格值动态决定外观可进一步阅读 条件格式化指南。结果配置完成后网格会按你声明的类名、内联样式与边框定义渲染由于格式化逻辑renderer、类名、边框元数据在每次渲染时都会重新执行格式在滚动、编辑与数据更新后始终保持一致。【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表