u
This commit is contained in:
1 parent
78eb811ff7
commit
97fe2ff306
83 files changed
+10083
-3662
No files matched your search
@@ -1,80 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// 最小用法:只喂 files + categories,上传 / 删除交给业务(组件不发请求)
|
||||
import { ref } from 'vue'
|
||||
import { G3Attachment } from '@g3soft/ui'
|
||||
import type { AttachmentCategory, AttachmentItem, AttachmentUploadContext } from '@g3soft/ui'
|
||||
|
||||
// 分类(可选):不给 categories 就只渲染「列表 + 预览」两栏
|
||||
const categories: AttachmentCategory[] = [
|
||||
{ id: 'contract', name: '合同文件' },
|
||||
{ id: 'invoice', name: '发票凭证' },
|
||||
{ id: 'photo', name: '现场照片' },
|
||||
]
|
||||
|
||||
// 内联 SVG,保证文档站离线也能看到图片预览
|
||||
const PHOTO = `data:image/svg+xml;utf8,${encodeURIComponent(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="320" height="200"><rect width="320" height="200" fill="#e5e7eb"/><text x="160" y="108" font-size="18" text-anchor="middle" fill="#6b7280">现场照片</text></svg>',
|
||||
)}`
|
||||
|
||||
const files = ref<AttachmentItem[]>([
|
||||
{ id: 1, name: '2026年度框架合同.pdf', size: 512_000, categoryId: 'contract' },
|
||||
{ id: 2, name: '供应商报价明细.xlsx', size: 86_000, categoryId: 'invoice' },
|
||||
{ id: 3, name: '现场照片.jpg', size: 1_240_000, categoryId: 'photo', url: PHOTO },
|
||||
{ id: 4, name: '验收纪要.docx', size: 24_000, categoryId: 'contract' },
|
||||
])
|
||||
|
||||
const lastEvent = ref('等待操作…')
|
||||
|
||||
// 没传 upload-request 时,组件把待上传文件抛出来,落库由业务决定
|
||||
function onUpload(incoming: File[], context: AttachmentUploadContext) {
|
||||
files.value = [
|
||||
...files.value,
|
||||
...incoming.map((file, index) => ({
|
||||
id: `local-${Date.now()}-${index}`,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
categoryId: context.categoryId,
|
||||
// 真实项目换成接口返回的地址;示例用 blob 地址即时预览
|
||||
url: URL.createObjectURL(file),
|
||||
})),
|
||||
]
|
||||
lastEvent.value = `upload:${incoming.map((file) => file.name).join('、')}`
|
||||
}
|
||||
|
||||
function onRemove(items: AttachmentItem[]) {
|
||||
const removed = new Set(items.map((item) => item.id))
|
||||
files.value = files.value.filter((file) => !removed.has(file.id))
|
||||
lastEvent.value = `remove:${items.map((item) => item.name).join('、')}`
|
||||
}
|
||||
|
||||
function onDownload(items: AttachmentItem[]) {
|
||||
lastEvent.value = `download:${items.map((item) => item.name).join('、')}`
|
||||
}
|
||||
|
||||
function onInvalid(info: { message: string }) {
|
||||
lastEvent.value = `invalid:${info.message}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<G3Attachment
|
||||
v-model:files="files"
|
||||
:categories="categories"
|
||||
:height="560"
|
||||
@upload="onUpload"
|
||||
@remove="onRemove"
|
||||
@download="onDownload"
|
||||
@invalid="onInvalid"
|
||||
/>
|
||||
<p class="hint">{{ lastEvent }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hint {
|
||||
margin: 8px 0 0;
|
||||
color: #8c8c8c;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,58 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// 弹窗用法:业务自己用 G3Modal 包一层,附件组件并不知道「弹窗」的存在
|
||||
import { ref } from 'vue'
|
||||
import { G3Attachment, G3Button, G3Modal } from '@g3soft/ui'
|
||||
import type { AttachmentItem, AttachmentUploadContext } from '@g3soft/ui'
|
||||
|
||||
const open = ref(false)
|
||||
|
||||
// 从空列表开始:正好看到空态投放区 → 入队(底栏变"脏")→ 上传的完整过程
|
||||
const files = ref<AttachmentItem[]>([])
|
||||
|
||||
const lastEvent = ref('')
|
||||
|
||||
function onUpload(incoming: File[], context: AttachmentUploadContext) {
|
||||
files.value = [
|
||||
...files.value,
|
||||
...incoming.map((file, index) => ({
|
||||
id: `local-${Date.now()}-${index}`,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
categoryId: context.categoryId,
|
||||
url: URL.createObjectURL(file),
|
||||
})),
|
||||
]
|
||||
lastEvent.value = `已加入 ${incoming.length} 个文件`
|
||||
}
|
||||
|
||||
function onRemove(items: AttachmentItem[]) {
|
||||
const removed = new Set(items.map((item) => item.id))
|
||||
files.value = files.value.filter((file) => !removed.has(file.id))
|
||||
lastEvent.value = `已删除 ${items.length} 个文件`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<G3Button @click="open = true">打开附件管理</G3Button>
|
||||
<p class="hint">{{ lastEvent }}</p>
|
||||
|
||||
<!-- 弹窗高度用 vh,附件组件再按 100% 撑满;不给 categories 就只有列表一栏 -->
|
||||
<G3Modal v-model:open="open" title="附件管理" width="80%" :fullscreen="false">
|
||||
<G3Attachment
|
||||
v-model:files="files"
|
||||
height="60vh"
|
||||
@upload="onUpload"
|
||||
@remove="onRemove"
|
||||
/>
|
||||
</G3Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hint {
|
||||
margin: 8px 0 0;
|
||||
color: #8c8c8c;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,20 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// 只读:隐藏上传 / 删除入口,只保留浏览与下载
|
||||
import { G3Attachment } from '@g3soft/ui'
|
||||
import type { AttachmentItem } from '@g3soft/ui'
|
||||
|
||||
const PHOTO = `data:image/svg+xml;utf8,${encodeURIComponent(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="320" height="200"><rect width="320" height="200" fill="#dbeafe"/><text x="160" y="108" font-size="18" text-anchor="middle" fill="#1d4ed8">现场照片</text></svg>',
|
||||
)}`
|
||||
|
||||
const files: AttachmentItem[] = [
|
||||
{ id: 1, name: '立项批复.pdf', size: 320_000 },
|
||||
{ id: 2, name: '现场照片.jpg', size: 1_024_000, url: PHOTO },
|
||||
{ id: 3, name: '预算表.xlsx', size: 64_000 },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- readonly 同时关掉「全选 / 批量删除 / 底栏上传」,拖拽与粘贴也会失效 -->
|
||||
<G3Attachment :files="files" readonly :height="420" />
|
||||
</template>
|
||||
@@ -1,61 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// 多选与批量操作:勾选后工具栏浮出「下载 / 删除」,行为全部走事件
|
||||
import { ref } from 'vue'
|
||||
import { G3Attachment } from '@g3soft/ui'
|
||||
import type { AttachmentItem } from '@g3soft/ui'
|
||||
|
||||
const files = ref<AttachmentItem[]>([
|
||||
{ id: 'a1', name: '设备清单.xlsx', size: 128_000 },
|
||||
{ id: 'a2', name: '施工方案.pdf', size: 2_048_000 },
|
||||
{ id: 'a3', name: '进度汇报.pptx', size: 640_000 },
|
||||
{ id: 'a4', name: '材料验收单.docx', size: 32_000 },
|
||||
{ id: 'a5', name: '现场记录.zip', size: 8_192_000 },
|
||||
])
|
||||
|
||||
const selected = ref<AttachmentItem[]>([])
|
||||
const lastEvent = ref('')
|
||||
|
||||
function onSelect(items: AttachmentItem[]) {
|
||||
selected.value = items
|
||||
}
|
||||
|
||||
function onRemove(items: AttachmentItem[]) {
|
||||
const removed = new Set(items.map((item) => item.id))
|
||||
files.value = files.value.filter((file) => !removed.has(file.id))
|
||||
lastEvent.value = `remove:${items.map((item) => item.name).join('、')}`
|
||||
}
|
||||
|
||||
function onDownload(items: AttachmentItem[]) {
|
||||
// 真实项目里在这里调接口拿签名地址再下载
|
||||
lastEvent.value = `download:${items.map((item) => item.name).join('、')}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 每页 3 条演示分页;builtin-download 关掉后「下载」只上报事件 -->
|
||||
<G3Attachment
|
||||
v-model:files="files"
|
||||
:height="420"
|
||||
:builtin-download="false"
|
||||
:show-size-changer="true"
|
||||
:page-size="3"
|
||||
:page-size-options="[3, 5]"
|
||||
@select="onSelect"
|
||||
@remove="onRemove"
|
||||
@download="onDownload"
|
||||
/>
|
||||
<p class="hint">
|
||||
已选 {{ selected.length }} 个<span v-if="selected.length">:{{ selected.map((item) => item.name).join('、') }}</span>
|
||||
<template v-if="lastEvent"> | {{ lastEvent }}</template>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hint {
|
||||
margin: 8px 0 0;
|
||||
color: #8c8c8c;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
// 列表样式 / 预览 / 打印 / 整理格式 / 源代码
|
||||
import { ref } from 'vue'
|
||||
import { G3Button, G3RichText, G3Space } from '@g3soft/ui'
|
||||
import type { RichTextCleanupResult, RichTextExpose } from '@g3soft/ui'
|
||||
|
||||
// 内含一段带空段落的正文,便于演示「整理格式」
|
||||
const html = ref(
|
||||
'<h2>季度总结</h2><p>本季度完成如下事项:</p><ul type="square"><li><p>上线 A 模块</p></li><li><p>修复 B 缺陷</p></li></ul><ol type="I"><li><p>需求评审</p></li><li><p>技术方案</p></li></ol><p></p><p></p><p>备注:以上内容见附件。</p>',
|
||||
)
|
||||
|
||||
const editorRef = ref<RichTextExpose | null>(null)
|
||||
const cleanupText = ref('')
|
||||
|
||||
/** 整理格式:清理空段落 / 空白文本 / 空行内记号,并把统计显示出来 */
|
||||
function tidy() {
|
||||
const result: RichTextCleanupResult | undefined = editorRef.value?.tidyFormat()
|
||||
if (!result) return
|
||||
cleanupText.value = result.changed
|
||||
? `清理了 ${result.removedEmptyParagraphs} 个空段落、${result.trimmedBlankTexts} 处空白文本、${result.removedEmptyMarks} 个空格式`
|
||||
: '没有需要整理的内容'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<G3Space vertical :size="12" style="display: flex">
|
||||
<G3Space :size="8">
|
||||
<G3Button size="small" type="outline" @click="tidy">整理格式(ref)</G3Button>
|
||||
<G3Button size="small" type="outline" @click="editorRef?.openPreview()">预览</G3Button>
|
||||
<G3Button size="small" type="outline" @click="editorRef?.print()">打印</G3Button>
|
||||
<G3Button size="small" type="outline" @click="editorRef?.openSourceCode()">源代码</G3Button>
|
||||
</G3Space>
|
||||
|
||||
<!-- 列表样式在「更多 → 无序列表样式 / 有序列表样式」里选 -->
|
||||
<G3RichText ref="editorRef" v-model="html" :min-height="220" />
|
||||
|
||||
<p v-if="cleanupText" style="font-size: 13px; color: #666">{{ cleanupText }}</p>
|
||||
</G3Space>
|
||||
</template>
|
||||
@@ -0,0 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Pencil, Trash2 } from '@lucide/vue'
|
||||
import { G3Message, G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 操作列:列上加 actions 即可,渲染成一排小按钮。
|
||||
// - type: 'more' 的项会收进「更多」下拉(这里没配,全部内联显示)
|
||||
// - confirm 给字符串或对象时先弹确认框,确认后才执行 onClick
|
||||
// - 操作列建议显式写 resizable: false(宽度由内容决定,拖了不落库)
|
||||
const columns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'name', title: '名称', width: 180 },
|
||||
{ dataIndex: 'amount', title: '金额', width: 120, align: 'right' },
|
||||
{
|
||||
dataIndex: 'op',
|
||||
title: '操作',
|
||||
width: 160,
|
||||
resizable: false,
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
icon: Pencil,
|
||||
onClick: (row) => G3Message.info(`编辑:${row.name}`),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
icon: Trash2,
|
||||
type: 'danger',
|
||||
confirm: { title: '确认删除', description: '删除后不可恢复,确定继续吗?' },
|
||||
onClick: (row) => G3Message.success(`已删除:${row.name}`),
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const data = ref<TableRow[]>([
|
||||
{ id: 1, name: '框架合同', amount: 120000 },
|
||||
{ id: 2, name: '采购订单', amount: 86000 },
|
||||
{ id: 3, name: '验收单', amount: 43000 },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="height: 260px">
|
||||
<G3Table :columns="columns" :data-source="data" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 列定义:dataIndex 指向行数据的字段
|
||||
const columns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'name', title: '名称', width: 180 },
|
||||
{ dataIndex: 'amount', title: '金额', width: 120, align: 'right' },
|
||||
{ dataIndex: 'owner', title: '负责人' },
|
||||
]
|
||||
|
||||
// seq 默认开启(最前面的序号列),bordered 默认 true
|
||||
const data = ref<TableRow[]>([
|
||||
{ id: 1, name: '框架合同', amount: 120000, owner: '张三' },
|
||||
{ id: 2, name: '采购订单', amount: 86000, owner: '李四' },
|
||||
{ id: 3, name: '验收单', amount: 43000, owner: '王五' },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="height: 260px">
|
||||
<G3Table :columns="columns" :data-source="data" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 行内编辑:列上加 editor 即可。
|
||||
// 单击单元格进入编辑;Enter 确认、Esc 取消。值变化通过 change 事件抛出。
|
||||
//
|
||||
// 编辑器类型:text / number / textarea / select / checkbox
|
||||
// checkbox 约定 1 = 选中、0 = 未选中(与后端 tinyint 对齐)。
|
||||
const columns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'name', title: '名称', width: 200, editor: { type: 'text' } },
|
||||
{
|
||||
dataIndex: 'status',
|
||||
title: '状态',
|
||||
width: 140,
|
||||
editor: {
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '启用', value: 1 },
|
||||
{ label: '停用', value: 0 },
|
||||
],
|
||||
},
|
||||
},
|
||||
{ dataIndex: 'enabled', title: '启用', width: 80, editor: { type: 'checkbox' } },
|
||||
{ dataIndex: 'qty', title: '数量', width: 120, align: 'right', editor: { type: 'number' } },
|
||||
]
|
||||
|
||||
const data = ref<TableRow[]>([
|
||||
{ id: 1, name: '框架合同', status: 1, enabled: 1, qty: 12 },
|
||||
{ id: 2, name: '采购订单', status: 0, enabled: 0, qty: 45 },
|
||||
])
|
||||
|
||||
const lastChange = ref('')
|
||||
|
||||
function onChange(row: TableRow, col: G3TableColumn<TableRow>, value: unknown) {
|
||||
lastChange.value = `${row.name} 的「${col.title}」改为 ${value}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p style="margin: 0 0 8px; color: #666; font-size: 13px">
|
||||
最近一次修改:{{ lastChange || '(点击单元格试试)' }}
|
||||
</p>
|
||||
<div style="height: 240px">
|
||||
<G3Table :columns="columns" :data-source="data" :seq="false" @change="onChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 列宽 / 列序拖拽与「列定义回写」:
|
||||
// 两者都要求用 v-model:columns 绑定,否则组件拖完无处回写(松手回弹),
|
||||
// 组件检测到没绑定会直接关掉这两个功能。
|
||||
const columns = ref<G3TableColumn<TableRow>[]>([
|
||||
{ dataIndex: 'name', title: '名称(可拖宽)', width: 200 },
|
||||
{ dataIndex: 'amount', title: '金额', width: 140, align: 'right' },
|
||||
{ dataIndex: 'owner', title: '负责人', width: 140 },
|
||||
// 操作列声明 resizable: false 后不可拖宽
|
||||
{ dataIndex: 'op', title: '操作', width: 100, resizable: false },
|
||||
])
|
||||
|
||||
// 行拖拽排序:开启后显示拖拽手柄,拖完通过 row-order-change 回传新顺序
|
||||
const dragColumns = ref<G3TableColumn<TableRow>[]>([
|
||||
{ dataIndex: 'name', title: '名称' },
|
||||
{ dataIndex: 'amount', title: '金额', align: 'right' },
|
||||
])
|
||||
|
||||
const data = ref<TableRow[]>([
|
||||
{ id: 1, name: '框架合同', amount: 120000, owner: '张三', op: '—' },
|
||||
{ id: 2, name: '采购订单', amount: 86000, owner: '李四', op: '—' },
|
||||
{ id: 3, name: '验收单', amount: 43000, owner: '王五', op: '—' },
|
||||
])
|
||||
|
||||
const dragData = ref<TableRow[]>([
|
||||
{ id: 1, name: '第一步', amount: 100 },
|
||||
{ id: 2, name: '第二步', amount: 200 },
|
||||
{ id: 3, name: '第三步', amount: 300 },
|
||||
])
|
||||
|
||||
const orderText = ref('')
|
||||
|
||||
function onRowOrderChange(rows: TableRow[]) {
|
||||
dragData.value = rows
|
||||
orderText.value = rows.map((row) => row.name).join(' → ')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p style="margin: 0 0 8px; color: #666; font-size: 13px">
|
||||
拖动表头分隔线改列宽、拖表头文字改列序。
|
||||
</p>
|
||||
<div style="height: 240px">
|
||||
<G3Table v-model:columns="columns" :data-source="data" :row-selection="null" />
|
||||
</div>
|
||||
|
||||
<p style="margin: 16px 0 8px; color: #666; font-size: 13px">
|
||||
行拖拽排序:{{ orderText || '(拖动左侧手柄试试)' }}
|
||||
</p>
|
||||
<div style="height: 200px">
|
||||
<G3Table
|
||||
v-model:columns="dragColumns"
|
||||
:data-source="dragData"
|
||||
:seq="false"
|
||||
row-draggable
|
||||
@row-order-change="onRowOrderChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 多选:传 rowSelection 即在最前注入选择列。
|
||||
// getCheckboxProps 可禁用个别行(禁用行不参与「全选」的分母)。
|
||||
const columns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'name', title: '名称', width: 180 },
|
||||
{ dataIndex: 'amount', title: '金额', width: 120, align: 'right' },
|
||||
]
|
||||
|
||||
const data: TableRow[] = [
|
||||
{ id: 1, name: '框架合同', amount: 120000 },
|
||||
{ id: 2, name: '采购订单', amount: 86000, locked: true },
|
||||
{ id: 3, name: '验收单', amount: 43000 },
|
||||
]
|
||||
|
||||
const selectedRowKeys = ref<Array<string | number>>([])
|
||||
const selectedText = ref('')
|
||||
|
||||
function onSelectionChange(keys: Array<string | number>, rows: TableRow[]) {
|
||||
selectedRowKeys.value = keys
|
||||
selectedText.value = rows.map((row) => row.name).join('、')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p style="margin: 0 0 8px; color: #666; font-size: 13px">
|
||||
已选:{{ selectedText || '(无)' }}
|
||||
</p>
|
||||
<div style="height: 260px">
|
||||
<G3Table
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
:row-selection="{
|
||||
selectedRowKeys,
|
||||
onChange: onSelectionChange,
|
||||
getCheckboxProps: (row) => ({ disabled: Boolean(row.locked) }),
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 排序:列上加 sorter: true 即可点表头排序(组件内排,不请求接口)。
|
||||
// sortType 决定按数字还是字符串比较,默认按字符串。
|
||||
const columns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'name', title: '名称', width: 180 },
|
||||
{ dataIndex: 'amount', title: '金额', width: 140, align: 'right', sorter: true, sortType: 'number' },
|
||||
{ dataIndex: 'qty', title: '数量', width: 120, align: 'right', sorter: true, sortType: 'number' },
|
||||
]
|
||||
|
||||
const data = ref<TableRow[]>([
|
||||
{ id: 1, name: '框架合同', amount: 120000, qty: 12 },
|
||||
{ id: 2, name: '采购订单', amount: 86000, qty: 45 },
|
||||
{ id: 3, name: '验收单', amount: 43000, qty: 7 },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="height: 260px">
|
||||
<G3Table :columns="columns" :data-source="data" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { G3Table } from '@g3soft/ui'
|
||||
import type { G3TableColumn, TableRow } from '@g3soft/ui'
|
||||
|
||||
// 性能门控:行数超过 100 才开启纵向虚拟滚动。
|
||||
// 组件内部按 dataSource.length 自动判断,业务不需要手动切换 virtual。
|
||||
const rowCount = ref(5000)
|
||||
const virtualColumns: G3TableColumn<TableRow>[] = [
|
||||
{ dataIndex: 'id', title: 'ID', width: 90 },
|
||||
{ dataIndex: 'name', title: '名称', width: 200 },
|
||||
{ dataIndex: 'value', title: '数值', width: 140, align: 'right' },
|
||||
]
|
||||
|
||||
const virtualData = computed(() =>
|
||||
Array.from({ length: rowCount.value }, (_, i) => ({
|
||||
id: i + 1,
|
||||
name: `记录 ${i + 1}`,
|
||||
value: (i + 1) * 7,
|
||||
})),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p style="margin: 0 0 8px; color: #666; font-size: 13px">
|
||||
当前 {{ rowCount }} 行 → {{ rowCount > 100 ? '已开启' : '未开启(行数不足 100 时全量渲染)' }}纵向虚拟滚动
|
||||
</p>
|
||||
<div style="height: 320px">
|
||||
<G3Table :columns="virtualColumns" :data-source="virtualData" :seq="false" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user