From a033b2dbb39a6eecb7a843d12e81f722d078a19d Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Tue, 7 Jul 2026 00:17:32 +0800 Subject: [PATCH] =?UTF-8?q?docs(datatable):=20=E9=87=8D=E6=9E=84=20README?= =?UTF-8?q?=EF=BC=88by=20AI=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 470 +++++++++++++++++++++++++++++++++++++++++++++------ package.json | 2 +- 2 files changed, 419 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 7320f57..e958120 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,443 @@ -# @apigo.cc/datatable AI 开发指南 +# @apigo.cc/datatable -`@apigo.cc/datatable` 是一个高性能、无状态的 Web 数据表格组件,支持万级数据虚拟滚动、多维编辑及固定列。 +`@apigo.cc/datatable` 是建立在 `@apigo.cc/base` 上的同步数据表格组件,重点不是“能显示表格”,而是“能直接被页面首屏加载并完成渲染、筛选、编辑和保存”。 ---- +## 目录 -## 一、 快速开始 +- [先看依赖](#先看依赖) - 同步加载顺序 +- [全局对象](#全局对象) - 字段类型注册入口 +- [``](#datatable) - 高性能表格组件 +- [字段定义](#字段定义) +- [内置编辑能力](#内置编辑能力) +- [筛选、排序、固定列](#筛选排序固定列) +- [复制粘贴与批量编辑](#复制粘贴与批量编辑) +- [自定义字段类型](#自定义字段类型) +- [推荐示例](#推荐示例) + +## 先看依赖 + +`datatable` 依赖 `state`、`bootstrap` 和 `base`,加载顺序仍然必须是同步的。 + +### 推荐加载顺序 -### 1. 引入依赖 ```html - + + + +``` + +## 全局对象 + +### `DataTable` + +`DataTable` 是本包挂到全局的对象。 + +```html + ``` -### 2. 导出清单 -* **Components**: `` +### 方法 ---- +| 方法 | 说明 | +|---|---| +| `registerFieldType(config)` | 注册字段类型 | +| `getFieldTypes()` | 获取当前所有已注册字段类型 | -## 二、 核心功能 +## `` -### 1. 虚拟滚动与 AOT 预编译 -通过 `$.state.list` 绑定大数据集。组件采用 **AOT (Ahead-of-Time) 模板预编译**技术,自动消除嵌套循环,实现万级数据的秒级渲染。 +`` 负责渲染、编辑、筛选、排序和虚拟滚动。内部会用到 ``, ``, ``,这些都来自 `base`。 -### 2. 极速排序与筛选 -支持本地数据的瞬间排序与筛选。 -* **交互**: 点击表头下拉菜单,支持升序/降序、文本搜索。 -* **性能**: 基于 `_refExt` 注入机制,更新 800+ 单元格仅需百毫秒级 Paint 耗时。 +### 绑定方式 -### 3. 多维编辑 -* **行内编辑**: 双击单元格利用 `AutoForm` 自动匹配类型。高度自适应父容器,支持 `textarea`, `switch` 等。 -* **状态同步**: 利用全局 `State` 机,实现零延迟的数据回写。 +| 名称 | 写法示例 | 说明 | +|---|---|---| +| `editable` | `` | 开启编辑、删除、字段管理、保存按钮 | +| `$.state.fields` | `$.state.fields="window.fields"` | 字段定义数组 | +| `$.state.list` | `$.state.list="window.list"` | 数据行数组 | -### 4. 固定列与紧凑状态栏 -* 在 `fields` 定义中设置 `pinned: 'left'` 或 `pinned: 'right'`。 -* 底部状态栏采用 `1 / 1000` 紧凑格式,集成快捷删除按钮。 +### 事件 ---- +| 事件 | 触发时机 | `detail` | +|---|---|---| +| `save` | 点击底部保存按钮 | `{ list, fields }` | +| `savefields` | 字段新增 / 编辑 / 删除后 | `fields` | +| `remove` | 删除行后 | `{ items }` | -## 三、 API 参考 +### 常用状态 -### `` 属性与事件 +| 名称 | 说明 | +|---|---| +| `editable` | 是否开启编辑模式 | +| `list` | 当前生效的数据列表,排序和筛选后会更新这里 | +| `fields` | 字段定义数组 | +| `_renderedList` | 当前 DOM 实际渲染的片段 | +| `prevHeight` | 虚拟滚动顶部占位高度 | +| `postHeight` | 虚拟滚动底部占位高度 | +| `_listStartIndex` | 当前渲染片段在原列表中的起始索引 | +| `selectedRowCount` | 当前选中行数 | +| `_originalList` | 原始数据快照,排序 / 筛选前的数据源 | +| `sortConfig` | `{ fieldId, direction }` | +| `filterConfig` | `{ [fieldId]: { mode, value, value2, selectedValues } }` | +| `activeFieldId` | 当前打开列菜单的字段 id | +| `activeField` | 当前打开列菜单的字段对象 | +| `activeModes` | 当前列允许的筛选模式 | +| `_columnStats` | 当前列高频值统计 | +| `_internalUpdate` | 内部同步标记,避免列表回写时触发二次筛选 | +| `_appliedHash` | 内部哈希缓存 | +| `_fieldsDirty` | 字段变更标记 | +| `_masterCellNodes` | 用于动态重建列模板的内部缓存 | +| `isDirty` | 是否存在未保存修改 | +| `isBulkEdit` | 是否处于批量编辑状态 | -| 属性 | 类型 | 说明 | -| :--- | :--- | :--- | -| `$.state.fields` | `Array` | 字段定义清单 | -| `$.state.list` | `Array` | 数据列表 | +### 方法 -| 事件 | 参数 | 说明 | -| :--- | :--- | :--- | -| `@update` | `{row, field, value, oldValue, isComplex}` | 单元格或复杂编辑器数据更新 | -| `@delete` | `{row}` | 行删除请求 | +| 方法 | 写法示例 | 说明 | +|---|---|---| +| `addRow()` | `table.addRow()` | 新增一行空数据 | +| `deleteSelectedRow()` | `table.deleteSelectedRow()` | 删除当前选区对应的行 | +| `saveChanges()` | `table.saveChanges()` | 派发 `save` 事件 | +| `addField()` | `table.addField()` | 新增字段 | +| `editField()` | `table.editField()` | 编辑当前打开菜单的字段 | +| `deleteField()` | `table.deleteField()` | 删除当前打开菜单的字段 | +| `showColumnMenu(field, event)` | `table.showColumnMenu(field, event)` | 打开列菜单 | +| `hideColumnMenu()` | `table.hideColumnMenu()` | 关闭列菜单 | +| `editCell(row, field, cellNode)` | `table.editCell(row, field, cellNode)` | 打开单元格编辑器 | +| `onScroll()` | `table.onScroll()` | 滚动时刷新虚拟列表 | -**字段定义结构 (`field`):** -```json +### 推荐示例 + +```html + + +
+ + +
+``` + +## 字段定义 + +`fields` 是表格最重要的配置。每个字段都建议写完整,不要只写一个 `id` 就了事。 + +### 字段结构 + +| 字段 | 写法示例 | 说明 | +|---|---|---| +| `id` | `id: 'name'` | 列唯一标识,同时也是数据行中的字段名 | +| `name` | `name: 'Name'` | 表头显示名 | +| `type` | `type: 'string'` | 列的原始类型 | +| `memo` | `memo: 'User name'` | 字段备注,字段编辑器可见 | +| `isIndex` | `isIndex: true` | 是否索引字段 | +| `settings` | `settings: { width: 160, formType: 'text' }` | 编辑与展示配置 | +| `formatter` | `formatter: v => String(v)` | 自定义显示格式 | + +### `settings` 字段 + +| 字段 | 写法示例 | 说明 | +|---|---|---| +| `width` | `width: 160` | 列宽,默认 `150` | +| `pinned` | `pinned: 'left'` | 固定列,`left` 或 `right` | +| `formType` | `formType: 'select'` | 编辑器类型 | +| `options` | `options: [{ label: 'A', value: 'a' }]` | 选择类选项 | +| `decimals` | `decimals: 2` | 数字小数位 | +| `prefix` | `prefix: '$'` | 数字前缀 | +| `suffix` | `suffix: '%'` | 数字后缀 | +| `thousandSep` | `thousandSep: true` | 数字千分位 | +| `labelOn` | `labelOn: 'YES'` | `switch` 为真时显示 | +| `labelOff` | `labelOff: 'NO'` | `switch` 为假时显示 | +| `format` | `format: 'YYYY-MM-DD'` | 日期时间格式说明 | +| `placeholder` | `placeholder: 'Enter value'` | 文本占位符 | + +### 字段示例 + +```js { - "id": "unique_id", - "name": "Display Name", - "type": "text | number | select | json", - "width": 150, - "pinned": "left | right", - "options": ["A", "B"] // 仅 select 类型 + id: 'score', + name: 'Score', + type: 'number', + settings: { + width: 120, + formType: 'number', + decimals: 2, + prefix: '$', + thousandSep: true + }, + formatter: value => value == null ? '' : String(value) } ``` ---- +## 内置编辑能力 -## 四、 最佳实践 -1. **保持无状态**:始终通过 `@update` 事件在外部更新数据源。 -2. **样式隔离**:优先使用组件提供的工具栏插槽 `
`。 +### 单元格编辑支持的 `formType` + +`editCell()` 会把 `settings.formType || type || 'text'` 交给 `AutoForm`,因此这些类型都能直接编辑: + +- `text` +- `number` +- `select` +- `checkbox` +- `radio` +- `switch` +- `date` +- `datetime` +- `textarea` +- `TagsInput` +- `DatePicker` +- `ColorPicker` +- `IconPicker` + +### 字段编辑器默认可选类型 + +字段管理弹窗里,默认由 `DataTable.getFieldTypes()` 提供的类型是: + +- `text` +- `number` +- `select` +- `checkbox` +- `switch` +- `datetime` +- `textarea` + +### 重要区别 + +- `date`、`radio` 这些类型在单元格编辑里是可用的 +- 但默认字段编辑器列表里不一定出现 +- 如果你要让它们出现在字段管理弹窗里,直接用 `registerFieldType()` 补进去 + +### 默认字段类型的格式化规则 + +| 类型 | 显示规则 | +|---|---| +| `text` | 原样字符串化 | +| `number` | 支持 `decimals`、`prefix`、`suffix`、`thousandSep` | +| `select` | 显示匹配项的 `label` | +| `checkbox` | 把多选项 label 用逗号拼接 | +| `switch` | `true` 显示 `labelOn` 或 `Yes`,`false` 显示 `labelOff` 或 `No` | +| `datetime` | 默认字符串化 | +| `textarea` | 默认字符串化 | + +## 筛选、排序、固定列 + +### 排序 + +- 点击表头右侧下拉按钮 +- 选择 `ASC` 或 `DESC` +- 排序状态写在 `state.sortConfig` + +### 筛选 + +列菜单支持三类筛选: + +- 文本类:`contains`, `equals`, `starts`, `ends` +- 数字类:`=`, `>`, `<`, `between` +- 值列表:直接勾选统计出来的高频值 + +### 支持的列筛选模式 + +| `formType` | 可用模式 | +|---|---| +| `text` | `contains`, `equals`, `starts`, `ends` | +| `textarea` | `contains`, `equals`, `starts`, `ends` | +| `number` | `=`, `>`, `<`, `between` | +| `date` | `=`, `>`, `<`, `between` | +| `select` | `contains`, `equals` | +| `TagsInput` | `contains`, `equals`, `starts`, `ends` | +| `switch`, `checkbox`, `radio` | 选项勾选,不走文本筛选模式 | + +### 固定列 + +字段上设置: + +```js +settings: { pinned: 'left' } +``` + +或: + +```js +settings: { pinned: 'right' } +``` + +就会固定在对应侧边。 + +## 复制粘贴与批量编辑 + +### 选择 + +- 鼠标拖选单元格区域 +- `selectedRowCount` 会同步更新 +- 选区会用于复制、粘贴和批量编辑 + +### 复制 + +- `Ctrl/Cmd + C` 把选区复制成 TSV +- 带引号、换行、制表符的值会自动转义 + +### 粘贴 + +- `Ctrl/Cmd + V` 会把剪贴板 TSV 回填到选区 +- 单格选中时会把后续数据按行列铺开 + +### 批量编辑 + +- 在已选中的区域内双击一个单元格 +- 如果选区跨多行,会进入批量编辑 +- 保存时会把新值写入范围内每一行 + +## 自定义字段类型 + +### `DataTable.registerFieldType(config)` + +```js +DataTable.registerFieldType({ + value: 'MyTags', + label: '{#Tags#}', + typeForDB: 'v4096', + schema: [ + { name: 'placeholder', label: 'Placeholder', type: 'text' } + ], + formatter: val => Array.isArray(val) ? val.join(' | ') : val +}) +``` + +### `schema` 说明 + +`schema` 的格式和 `base` 里的 `AutoForm.schema` 一样,所以这里也能用: + +- `name` +- `label` +- `type` +- `setting` +- `options` +- `if` + +### 适合注册的场景 + +- 你要让字段编辑器认识一个新的 `formType` +- 你要给某种值定义专用 `formatter` +- 你要把扩展控件复用到表格内联编辑里 + +## 推荐示例 + +### 可编辑表格 + +```html + + +
+ + +
+``` + +### 只读大表 + 虚拟滚动 + +```html + + +
+ + +
+``` + +### 自定义字段类型 + +```html + + + +``` + +### 备注 + +- 字段定义和数据列表建议放在 JS 里 +- 外层容器最好明确给高度 +- 需要保存时,监听 `save`;需要字段变更时,监听 `savefields` diff --git a/package.json b/package.json index c0f1db7..9e28d7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apigo.cc/datatable", - "version": "1.0.15", + "version": "1.0.16", "type": "module", "main": "dist/datatable.js", "module": "dist/datatable.js",