u
This commit is contained in:
1 parent
7bd5f1dde9
commit
f3936cec61
70 files changed
+13074
-187
No files matched your search
@@ -70,6 +70,25 @@ description: 高性能虚拟滚动表格,支持排序、固定列、多选、
|
||||
|
||||
编辑器的输入值先写进内部草稿,**失焦才落库并抛出 `change`**。这样每敲一个字符不会触发父级重渲染(否则光标会丢、输入法会断)。用 `editable={false}` 可整体禁用编辑。
|
||||
|
||||
### 编辑器形态:单元格内无外间距、无常驻边框
|
||||
|
||||
默认(`editorSeamless`)下编辑器的**外间距为 0、自身不画常驻边框**,整格铺满、融进表格:
|
||||
|
||||
- 适合整行编辑、键盘连续录入、固定列宽、专业用户(Excel / AG Grid / Handsontable 的表格态);
|
||||
- 单元格几何在进入 / 离开编辑时**完全不变**——编辑器的盒高就等于 `rowHeight`,同一行的纯文本列不会跟着跳;
|
||||
- 水平内边距由单元格统一提供(编辑器和纯文本格用同一套网格),**进出编辑态零位移**;
|
||||
- 视觉提示只在**焦点、hover 与校验**时出现,且都不占用布局空间:
|
||||
- 焦点 → 单元格内嵌的主色焦点环(`td:focus-within` 的内阴影)+ 输入框自身的焦点光晕;
|
||||
- hover → 格内极淡填充;
|
||||
- 校验(`status` = `error` / `warning`)→ 文字色 + 1px 内描边。
|
||||
|
||||
```vue
|
||||
<!-- 回到「格内留一圈间距 + 自身描边」的悬浮卡片观感 -->
|
||||
<G3Table :editor-seamless="false" :columns="columns" :data-source="data" />
|
||||
```
|
||||
|
||||
两种形态的**编辑器盒高都等于 `rowHeight`**,所以切换真值不会改变行高。`textarea` 编辑器在默认的 30px 行里放不下正文,需要显式给足 `row-height`。
|
||||
|
||||
### ⚠ 数据源必须是响应式的
|
||||
|
||||
**行对象必须能被 Vue 追踪**,否则编辑回写不会触发重渲染。典型的踩坑写法是用 `computed` 派生数据:
|
||||
@@ -92,6 +111,15 @@ watch(n, (v) => { rows.value = Array.from({ length: v }, (_, i) => makeRow(i)) }
|
||||
|
||||
开发模式下,进入编辑时会检测并打印一条警告指明改法(每个组件实例只警告一次)。
|
||||
|
||||
### 编辑期的只读列
|
||||
|
||||
某一列没有配 `editor` 时,它在编辑期**不可修改**。为了让人一眼看出「这格点不动」,
|
||||
该行里**没有编辑器的格子会自动铺一层灰底**、文字也降一档亮度——
|
||||
不需要业务额外配任何东西,也不需要加锁图标。
|
||||
|
||||
灰底只出现在**正在编辑的那一行**(其余行保持原样),且用 `--td-bgc` 叠中性色得到,
|
||||
所以亮 / 暗主题自动跟随。
|
||||
|
||||
<demo vue="table/editable.vue" />
|
||||
|
||||
## 操作列
|
||||
@@ -129,6 +157,7 @@ watch(n, (v) => { rows.value = Array.from({ length: v }, (_, i) => makeRow(i)) }
|
||||
| `seq` | `boolean \| { title?, width? }` | `true` | 序号列 |
|
||||
| `activeRowKey` | `string \| number \| null` | `null` | 当前高亮行 |
|
||||
| `editable` | `boolean` | `true` | 行内编辑总开关 |
|
||||
| `editorSeamless` | `boolean` | `true` | 编辑器无缝嵌入单元格:格内无外间距、无常驻边框,只有焦点 / hover / 校验态才给视觉提示。传 `false` 回到留间距 + 自身描边的形态 |
|
||||
| `noDataFull` | `boolean` | `true` | 空态铺满容器高度 |
|
||||
| `showOverflow` | `boolean` | `true` | 内容溢出省略 |
|
||||
| `autoFitWidth` | `boolean` | `false` | 非横向虚拟时铺满容器宽度(开启后关闭列宽拖拽) |
|
||||
@@ -159,6 +188,47 @@ watch(n, (v) => { rows.value = Array.from({ length: v }, (_, i) => makeRow(i)) }
|
||||
| `allowClear` | `boolean` | select 是否可清空,默认 `true` |
|
||||
| `emptyValue` | `unknown` | select 清空后落库的值,默认 `null` |
|
||||
| `onChange` | `(value, row, col) => void` | 本列值变化回调(早于组件的 `change`) |
|
||||
| `validate` | `(value, row, col) => boolean \| string` | 校验规则:**返回 falsy 表示通过**,返回非空 string 表示不通过(该字符串即错误原因)。 |
|
||||
| `errorStyle` | `'cell' \| 'inline'` | 校验失败的展示形态,默认 `'cell'`。见下 |
|
||||
|
||||
### 校验(`validate`)
|
||||
|
||||
给列配 `validate` 即可获得**实时校验**:
|
||||
|
||||
```ts
|
||||
{
|
||||
dataIndex: 'qty',
|
||||
title: '采购数量',
|
||||
editor: {
|
||||
type: 'number',
|
||||
// 返回 falsy = 通过;返回 string = 不通过,字符串即错误原因
|
||||
validate: (value) => Number(value) > 0 || '采购数量必须大于 0',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
三件需要知道的事:
|
||||
|
||||
- **返回值的语义是「falsy 通过 / string 不通过」**,不是「true 通过」。所以
|
||||
`validate: (v) => Number(v) > 0 || '必须大于 0'` 这种最自然的写法是对的;
|
||||
但若写成 `(v) => Number(v) > 0`(只返回布尔),则**永远不会报错**——
|
||||
布尔 `true` 被当作「通过」、`false` 也被当作「通过」。要让布尔参与判错,
|
||||
必须返回字符串。这一点容易踩,故单独说明。
|
||||
- **校验是派生值,不是一次性状态**:每次渲染都按当前行数据重算,
|
||||
所以用户把空值改成合法值后,红底与角标在下次渲染就自动消失,
|
||||
**不需要**业务手动清状态,组件内部也不维护任何 error 注册表。
|
||||
- **校验函数抛错会被吞掉**并降级为「通过」(仅 DEV 打印警告)。
|
||||
因为它在渲染期被调用,抛出去会让整格渲染失败,比「没有红底」严重得多。
|
||||
|
||||
#### 展示形态 `errorStyle`
|
||||
|
||||
| 值 | 效果 |
|
||||
| --- | --- |
|
||||
| `'cell'`(默认) | 单元格铺**浅红底** + 右上角 **`!` 角标**;聚焦时焦点环转为错误色 |
|
||||
| `'inline'` | 只在编辑器自身画文字色与 1px 内描边,**不**铺底、**不**加角标 |
|
||||
|
||||
浅红底取自设计原型,适合 ERP 明细这类以单元格为视觉单位的场景;
|
||||
若表格本身已经很密、或那一列很窄(角标会挤到文字),用 `'inline'` 更克制。
|
||||
|
||||
### `actions`
|
||||
|
||||
@@ -215,4 +285,5 @@ watch(n, (v) => { rows.value = Array.from({ length: v }, (_, i) => makeRow(i)) }
|
||||
- 没有圆角;`bordered: false` 时四边与格线全部消失。
|
||||
- **`--th-bgc` 等表头/表尾底色**由覆盖层的变量映射提供,不通过行内 style 注入。
|
||||
- **行编辑态存在 `WeakMap` 里**:按行对象存,不给业务数据打标记;行被回收时状态自动释放。行与行之间切换编辑**不翻转** `editingActive`,避免整表列重建。
|
||||
- **编辑器无缝嵌入单元格**(`editorSeamless`):把 `G3Input` / `G3Select` 自带的 `padding` / `border` / `border-radius` / `background` 置零,只保留焦点、hover 与校验提示;编辑器的高度由组件显式钉成 `var(--row-height)`(不能被控件的 `min-height: 32px` 顶高,也不能靠 `height: 100%` —— td 的内容盒不等于行高),因此**编辑前后的行高完全一致**。焦点环画在外层 `td` 的 `inset` 阴影上:不参与盒模型计算,几何零影响。
|
||||
- **RTL**:布局用逻辑属性,带符号位移走 `--g3-dir-sign`;分隔条拖拽与键盘方向由库的 `useDirection` 处理。
|
||||
Reference in new issue
Block a user