This commit is contained in:
oneao committed 2026-10-12 22:25:41 +08:00
1 parent ae3ca3cfa1
commit 7bd5f1dde9
45 files changed
+3414 -229

No files matched your search

+40 -5
View File
@@ -15,7 +15,7 @@ description: 高性能虚拟滚动表格,支持排序、固定列、多选、
## 基础用法
给 `columns` 与 `dataSource` 两份数据即可。序号列(`seq`)默认开启,外框与圆角默认有(`bordered`)。
给 `columns` 与 `dataSource` 两份数据即可。序号列(`seq`)默认开启,边框(`bordered`)默认有。
<demo vue="table/basic.vue" />
@@ -52,16 +52,46 @@ description: 高性能虚拟滚动表格,支持排序、固定列、多选、
## 行内编辑
列上加 `editor` 即可编辑:单击单元格进入,`Enter` 确认、`Esc` 取消。
列上加 `editor` 即可编辑:单击单元格进入。
| 按键 | 行为 |
| --- | --- |
| `Enter` | **全选当前内容**(便于直接覆写),不提交 |
| `Esc` | **取消编辑**:把该行恢复到进入编辑前的值,然后退出编辑 |
| 失焦(点别处 / Tab) | **提交**并抛出 `change` |
`Enter` 不做提交是刻意的:单元格里的值通常要整体替换,全选后直接输入即可,不必先手动清空。提交一律靠失焦。
| 编辑器类型 | 说明 |
| --- | --- |
| `text` / `number` / `textarea` | 用 [Input](/ui/form/input) 渲染 |
| `text` / `number` / `password` / `textarea` | 用 [Input](/ui/form/input) 渲染 |
| `select` | 用 [Select](/ui/form/select) 渲染;`options` 可以是数组,也可以是接收当前行的函数 |
| `checkbox` | 点击即切换,无需先激活整行;约定 `1` = 选中、`0` = 未选中(与后端 tinyint 对齐) |
编辑器的输入值先写进内部草稿,**失焦才落库并抛出 `change`**。这样每敲一个字符不会触发父级重渲染(否则光标会丢、输入法会断)。用 `editable={false}` 可整体禁用编辑。
### ⚠ 数据源必须是响应式的
**行对象必须能被 Vue 追踪**,否则编辑回写不会触发重渲染。典型的踩坑写法是用 `computed` 派生数据:
```ts
// ❌ 错:computed 返回的是普通对象数组,行字段不可追踪
const rows = computed(() => Array.from({ length: n.value }, (_, i) => makeRow(i)))
// ✅ 对:ref 会递归代理内部对象
const rows = ref<Row[]>([])
watch(n, (v) => { rows.value = Array.from({ length: v }, (_, i) => makeRow(i)) }, { immediate: true })
```
用错时的症状**极具迷惑性**,不容易联想到数据源:
- `change` 事件**照常抛出**(数据其实已经改了,父级能拿到)
- 但界面上**仍显示旧值**
- 点一下别处(触发无关重渲染)才「突然」更新
- 尤其是 `select` 编辑器:选完选项下拉关了、值却没变,很像组件的事件时序 bug
开发模式下,进入编辑时会检测并打印一条警告指明改法(每个组件实例只警告一次)。
<demo vue="table/editable.vue" />
## 操作列
@@ -91,7 +121,7 @@ description: 高性能虚拟滚动表格,支持排序、固定列、多选、
| `virtualX` | `boolean` | `true` | 横向虚拟滚动总开关(实际是否开启受列数门控) |
| `rowHeight` | `number` | `30` | 行高,同时驱动虚拟滚动计算 |
| `headerRowHeight` | `number` | `34` | 表头行高 |
| `bordered` | `boolean \| string` | `true` | 外框圆角描边 + 行分隔线;`false` 时只留行分隔线 |
| `bordered` | `boolean` | `true` | 是否显示边框(透传给底座的 `bordered: true`)。边框由底座绘制,不再是自绘外框 + 圆角 |
| `colResizable` | `boolean \| object` | `true` | 列宽拖拽;未绑定 `v-model:columns` 时自动关闭。可用 `{ disabled: (col) => boolean }` 按列禁用 |
| `columnDraggable` | `boolean \| object` | `true` | 列序拖拽;同上要求绑定 `v-model:columns` |
| `rowDraggable` | `boolean` | `false` | 行拖拽排序 |
@@ -178,6 +208,11 @@ description: 高性能虚拟滚动表格,支持排序、固定列、多选、
- 注意 SCSS 里**不能**写 `@use 'stk-table-vue/lib/style.css'`:带 `.css` 后缀时 Sass 不会内联,只原样输出一条 CSS `@import` 语句,产物里会留下一条浏览器解析不了的裸包路径。去掉后缀才会真正内联。
- **主题通过覆盖库的 CSS 变量实现**:库把 41 个主题值都做成了 `.stk-table` 作用域内的变量,组件把它们映射到 `--g3-*` 令牌(覆盖层在 `src/table/style/_overrides.scss`)。改变量而不是逐个选择器改样式,库升级时不容易失效。
- **区域选择按需自注册**:库的单元格区域选择是全局注册的(`registerFeature(useAreaSelection)`),不注册则 `area-selection-change` 永不触发、行内编辑失效。组件库不拥有 app 启动流程,因此**首次挂载时自动注册一次**;需要显式控制时可调用导出的 `registerTableFeatures()`。
- **`data-testid` 透传到内层**:组件 `inheritAttrs: false`,`$attrs` 落在内层 `StkTable` 上。外框 / 圆角在我们自己的根节点 `.g3-table` 上,写 E2E 时按类名定位根节点。
- **`data-testid` 透传到内层**:组件 `inheritAttrs: false`,`$attrs` 落在内层 `StkTable` 上,所以写 E2E 时按类名 `.g3-table` 定位根节点。
- **边框完全交给底座**:组件把 `bordered` 直接透传为底座的 `bordered: true`,**不再自绘外框与行分隔线**。因此:
- 底座用逐格 `background-image` 渐变画线(不是 `border`),横竖线都来自 `--bg-border-*` 变量;
- 受滚动条影响,**表格右侧与底部的边框会消失**——这是底座文档(`table/basic/bordered`)明确说明的行为,需要时自行补 CSS;
- 没有圆角;`bordered: false` 时四边与格线全部消失。
- **`--th-bgc` 等表头/表尾底色**由覆盖层的变量映射提供,不通过行内 style 注入。
- **行编辑态存在 `WeakMap` 里**:按行对象存,不给业务数据打标记;行被回收时状态自动释放。行与行之间切换编辑**不翻转** `editingActive`,避免整表列重建。
- **RTL**:布局用逻辑属性,带符号位移走 `--g3-dir-sign`;分隔条拖拽与键盘方向由库的 `useDirection` 处理。