This commit is contained in:
oneao committed 2026-10-08 22:38:34 +08:00
1 parent f572dce2f6
commit e99a9fb274
356 files changed
+28877 -1055

No files matched your search

@@ -0,0 +1,26 @@
<script setup lang="ts">
// 最小可用表单:model 提供数据、FormItem 的 name 对应字段、rules 声明校验
import { reactive } from 'vue'
import { G3Button, G3Form, G3FormItem, G3Input, G3Message } from '@g3soft/ui'
const model = reactive({ name: '' })
const rules = {
name: [{ required: true }],
}
function onSubmit(values: Record<string, unknown>) {
G3Message.success(`提交成功:${JSON.stringify(values)}`)
}
</script>
<template>
<G3Form :model="model" :rules="rules" :label-width="72" style="max-width: 360px" @submit="onSubmit">
<G3FormItem name="name" label="名称">
<G3Input v-model="model.name" placeholder="请输入名称" />
</G3FormItem>
<G3FormItem>
<G3Button html-type="submit">提交</G3Button>
</G3FormItem>
</G3Form>
</template>
@@ -0,0 +1,46 @@
<script setup lang="ts">
// 多列表单:columns 开启网格,FormItem 用 span 跨列、lineStart 强制换行
import { reactive } from 'vue'
import { G3Button, G3Form, G3FormItem, G3Input, G3Select } from '@g3soft/ui'
const model = reactive({
name: '',
code: '',
owner: undefined as number | undefined,
description: '',
})
</script>
<template>
<G3Form
:model="model"
layout="vertical"
:columns="2"
:gap="{ row: 16, col: 16 }"
style="max-width: 640px"
@submit="() => {}"
>
<G3FormItem name="name" label="项目名称">
<G3Input v-model="model.name" />
</G3FormItem>
<G3FormItem name="code" label="项目标识">
<G3Input v-model="model.code" />
</G3FormItem>
<G3FormItem name="owner" label="负责人">
<G3Select
v-model="model.owner"
:options="[
{ label: '张三', value: 1 },
{ label: '李四', value: 2 },
]"
/>
</G3FormItem>
<!-- span 2:占满整行 -->
<G3FormItem name="description" label="项目描述" :span="2">
<G3Input v-model="model.description" type="textarea" :rows="3" />
</G3FormItem>
<G3FormItem :span="2">
<G3Button html-type="submit">保存</G3Button>
</G3FormItem>
</G3Form>
</template>
@@ -0,0 +1,33 @@
<script setup lang="ts">
// FormGroup:在长表单里做「分组 + 组内独立列数」,组内覆盖组外布局
import { reactive } from 'vue'
import { G3Button, G3Form, G3FormGroup, G3FormItem, G3Input } from '@g3soft/ui'
const model = reactive({ host: '', port: '', username: '', password: '' })
</script>
<template>
<G3Form :model="model" layout="vertical" style="max-width: 620px" @submit="() => {}">
<G3FormGroup title="服务地址" :columns="2">
<G3FormItem name="host" label="主机">
<G3Input v-model="model.host" />
</G3FormItem>
<G3FormItem name="port" label="端口">
<G3Input v-model="model.port" type="number" />
</G3FormItem>
</G3FormGroup>
<G3FormGroup title="认证信息" :columns="2">
<G3FormItem name="username" label="账号">
<G3Input v-model="model.username" />
</G3FormItem>
<G3FormItem name="password" label="密码">
<G3Input v-model="model.password" type="password" />
</G3FormItem>
</G3FormGroup>
<G3FormItem>
<G3Button html-type="submit">连接</G3Button>
</G3FormItem>
</G3Form>
</template>
@@ -0,0 +1,37 @@
<script setup lang="ts">
// layout:horizontal 标签在左(默认,可配 labelAlign / labelWidth);vertical 标签在上
import { reactive } from 'vue'
import { G3Form, G3FormItem, G3Input, G3Space } from '@g3soft/ui'
const model = reactive({ name: '示例', desc: '' })
</script>
<template>
<G3Space direction="vertical" :size="24" style="display: flex">
<!-- 横向:labelAlign="right" + 120px 定宽,右侧控件对齐 -->
<G3Form
:model="model"
layout="horizontal"
label-align="right"
:label-width="120"
style="max-width: 420px"
>
<G3FormItem name="name" label="项目名称">
<G3Input v-model="model.name" />
</G3FormItem>
<G3FormItem name="desc" label="项目描述" extra="最多 50 字">
<G3Input v-model="model.desc" />
</G3FormItem>
</G3Form>
<!-- 纵向:label 在上,适合狭窄容器 -->
<G3Form :model="model" layout="vertical" style="max-width: 420px">
<G3FormItem name="name" label="项目名称">
<G3Input v-model="model.name" />
</G3FormItem>
<G3FormItem name="desc" label="项目描述">
<G3Input v-model="model.desc" type="textarea" :rows="3" />
</G3FormItem>
</G3Form>
</G3Space>
</template>
@@ -0,0 +1,61 @@
<script setup lang="ts">
// 规则字段:required / type / pattern / len / min / max / message / validator
import { reactive } from 'vue'
import { G3Button, G3Form, G3FormItem, G3Input, G3Message, G3Select } from '@g3soft/ui'
const model = reactive({ username: '', email: '', age: '', slug: '', role: undefined as number | undefined })
const rules = {
// required:为空时提示「用户名不能为空」
username: [{ required: true, min: 3, max: 12 }],
// type:内置 string / number / integer / email / url
email: [{ required: true, type: 'email' }],
// validator:返回 true / undefined 通过;返回 false 用 message,返回字符串则作为错误文案
age: [
{
validator: (value: unknown) =>
Number(value) >= 18 ? true : '必须年满 18 岁',
},
],
// pattern:正则
slug: [{ pattern: /^[a-z0-9-]+$/, message: '只能包含小写字母、数字与连字符' }],
// 自定义动态文案:message 传函数
role: [{ required: true, message: () => '请选择角色' }],
}
</script>
<template>
<G3Form
:model="model"
:rules="rules"
:label-width="88"
style="max-width: 420px"
@submit="(values: Record<string, unknown>) => G3Message.success(JSON.stringify(values))"
>
<G3FormItem name="username" label="用户名">
<G3Input v-model="model.username" placeholder="3-12 个字符" />
</G3FormItem>
<G3FormItem name="email" label="邮箱">
<G3Input v-model="model.email" placeholder="name@example.com" />
</G3FormItem>
<G3FormItem name="age" label="年龄">
<G3Input v-model="model.age" type="number" />
</G3FormItem>
<G3FormItem name="slug" label="标识">
<G3Input v-model="model.slug" placeholder="user-profile" />
</G3FormItem>
<G3FormItem name="role" label="角色">
<G3Select
v-model="model.role"
:options="[
{ label: '管理员', value: 1 },
{ label: '成员', value: 2 },
]"
placeholder="请选择"
/>
</G3FormItem>
<G3FormItem>
<G3Button html-type="submit">提交</G3Button>
</G3FormItem>
</G3Form>
</template>
@@ -0,0 +1,47 @@
<script setup lang="ts">
// 提交与失败:submit 只在全部通过时触发;submitFailed 带上出错字段
import { reactive, ref } from 'vue'
import { G3Button, G3Form, G3FormItem, G3Input, G3Message, G3Space } from '@g3soft/ui'
const model = reactive({ name: '', email: '' })
const rules = {
name: [{ required: true }],
email: [{ required: true, type: 'email' }],
}
const formRef = ref<InstanceType<typeof G3Form> | null>(null)
async function validateManually() {
const errors = await formRef.value?.validateAll()
if (!errors?.length) G3Message.success('校验通过')
else G3Message.error(`有 ${errors.length} 个字段未通过`)
}
</script>
<template>
<G3Space direction="vertical" :size="12" style="display: flex; max-width: 420px">
<G3Form
ref="formRef"
:model="model"
:rules="rules"
:label-width="72"
@submit="() => G3Message.success('全部通过,已提交')"
@submit-failed="(payload: { errorFields: unknown[] }) => G3Message.error(`失败:${payload.errorFields.length} 个字段`)"
@reset="G3Message.info('已重置')"
>
<G3FormItem name="name" label="名称">
<G3Input v-model="model.name" />
</G3FormItem>
<G3FormItem name="email" label="邮箱">
<G3Input v-model="model.email" />
</G3FormItem>
<G3FormItem>
<G3Space :size="8">
<G3Button html-type="submit">提交</G3Button>
<G3Button html-type="reset" type="outline">重置</G3Button>
<G3Button type="ghost" @click="validateManually">手动校验</G3Button>
</G3Space>
</G3FormItem>
</G3Form>
</G3Space>
</template>
@@ -0,0 +1,38 @@
<script setup lang="ts">
// validateTrigger:change(默认,输入即校验)或 blur(失焦才校验,输入过程不打扰)
import { reactive } from 'vue'
import { G3Form, G3FormItem, G3Input, G3Space } from '@g3soft/ui'
const changeModel = reactive({ code: '' })
const blurModel = reactive({ code: '' })
const rules = { code: [{ required: true, min: 4, message: '至少 4 位' }] }
</script>
<template>
<G3Space :size="24" wrap>
<G3Form
:model="changeModel"
:rules="rules"
validate-trigger="change"
layout="vertical"
style="width: 260px"
>
<G3FormItem name="code" label="change:输入即校验">
<G3Input v-model="changeModel.code" placeholder="试试输入 1 个字符" />
</G3FormItem>
</G3Form>
<G3Form
:model="blurModel"
:rules="rules"
validate-trigger="blur"
layout="vertical"
style="width: 260px"
>
<G3FormItem name="code" label="blur:失焦才校验">
<G3Input v-model="blurModel.code" placeholder="输入过程不报错" />
</G3FormItem>
</G3Form>
</G3Space>
</template>