102 lines
4.1 KiB
Vue
102 lines
4.1 KiB
Vue
<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>
|