Files
workspace/code/g3soft-libs/docs/examples/table/editable.vue
T
2026-10-16 17:30:17 +08:00

102 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { ref } from 'vue'
import { G3Table } from '@g3soft/ui'
import type { G3TableColumn, TableRow } from '@g3soft/ui'
// 行内编辑:列上加 editor 即可。**单击**单元格进入编辑(不需要双击)。
//
// 编辑器类型(注意 `input` 是统称,细分形态走 inputType):
// { type: 'input' } → 单行文本,用 G3Input 渲染
// { type: 'input', inputType: 'number' } → 数字
// { type: 'input', inputType: 'password' }
// { type: 'input', inputType: 'textarea' }
// { type: 'select' } → 用 G3Select 渲染;options 可传数组,
// 也可传「接收当前行的函数」
// { type: 'checkbox' } → 点击即切换,无需先激活整行;
// 约定 1 = 选中、0 = 未选中(对齐后端 tinyint)
//
// 关键行为:输入值先写进内部草稿,**失焦才落库并抛出 change**。
// 这样每敲一个字符不会触发父级重渲染(否则光标会丢、输入法会断)。
//
// 键盘:编辑态下 Enter 会全选当前格内容(可直接覆盖输入)、Esc 退出编辑;
// 方向键由表格接管移动选区(按住连按时会先等按键松开再挂编辑器,避免掉帧)。
//
// ⚠️ 数据源必须是响应式的:行对象要能被 Vue 追踪,否则改动不会触发重渲染
// (change 照常抛出,但界面仍显示旧值,且要等一次无关重渲染才更新)。
const columns: G3TableColumn<TableRow>[] = [
{ dataIndex: 'name', title: '名称', width: 200, editor: { type: 'input' } },
{
dataIndex: 'status',
title: '状态(select)',
width: 150,
editor: {
type: 'select',
options: [
{ label: '启用', value: 1 },
{ label: '停用', value: 0 },
],
},
},
{ dataIndex: 'enabled', title: '启用', width: 80, editor: { type: 'checkbox' } },
{
dataIndex: 'qty',
title: '数量(number)',
width: 140,
align: 'right',
editor: { type: 'input', inputType: 'number' },
},
{
dataIndex: 'remark',
title: '备注',
width: 180,
// 按行禁用:这一行「改不了」时该格只读(无需先点开)。
// 这里演示常见的「停用之后不许再改备注」——第 2 行 status=0。
editor: { type: 'input', disabled: (row) => row.status === 0 },
},
{
dataIndex: 'owner',
title: '负责人(options 依赖本行)',
width: 200,
// options 传函数时会收到当前行 —— 按「状态」给出不同候选人。
// 注意这类列在非编辑态会把值解析成 label 展示。
editor: {
type: 'select',
options: (row: TableRow) =>
row.status === 1
? [
{ label: '张三', value: '张三' },
{ label: '李四', value: '李四' },
]
: [{ label: '王五', value: '王五' }],
},
},
]
const data = ref<TableRow[]>([
{ id: 1, name: '框架合同', status: 1, enabled: 1, qty: 12, remark: '年度框架', owner: '张三' },
{ id: 2, name: '采购订单', status: 0, enabled: 0, qty: 45, remark: '', owner: '王五' },
])
const lastChange = ref('')
function onChange(row: TableRow, col: G3TableColumn<TableRow>, value: unknown) {
// 只有值**真的变化**才会走到这里(组件内部按编辑前的快照去重),
// 所以「点进去又点出来」不会产生无意义的 change。
lastChange.value = `「${row.name}」的「${col.title}」→ ${value}`
}
</script>
<template>
<div>
<p style="margin: 0 0 8px; color: #666; font-size: 13px">
最近一次 change:{{ lastChange || '(点击单元格试试)' }}
</p>
<p style="margin: 0 0 8px; color: #999; font-size: 12px">
单击进入编辑 · Enter 全选当前格 · Esc 退出 · 方向键移动选区 · 失焦提交
</p>
<div style="height: 240px">
<G3Table :columns="columns" :data-source="data" :seq="false" @change="onChange" />
</div>
</div>
</template>