本文展示「定义即表单」的核心能力:一个 Valibot 类型定义,会自动渲染为对应的表单控件。下面每个示例的定义都会渲染出一个可交互的表单。
所有渲染依赖全局字段配置 FieldGlobalConfig(string/number/boolean/picklist 等隐式类型映射到对应控件),通过 options 传入:
import { PresetDefine } from '@piying-lib/angular-daisyui/preset';
export const FieldGlobalConfig = PresetDefine;
options = { fieldGlobalConfig: FieldGlobalConfig };
大部分 Valibot 类型会被解析为表单控件,以下为常用类型映射。
type-string.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.string(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
type-number.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.number(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
type-boolean.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.boolean(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
type-picklist.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.picklist(['v1', 'v2', 'v3']),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
v.object() 定义的对象会渲染为一个表单组,自动包含所有子字段。表单组内部都可以通过 __helper 引用 formHelper 组件,展示校验错误与提交 / 重置按钮。
type-object.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.string(),
k2: v.number(),
k3: v.boolean(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
v.looseObject() 会保留未在 Schema 中显式定义的键值:
loose-object.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.looseObject({
k1: v.string(),
k2: v.number(),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { k1: 'v1', k2: 2 };
v.objectWithRest() 部分键值固定,其余键值按指定类型可动态添加:
object-with-rest.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.intersect([
v.objectWithRest(
{
k1: v.string(),
k2: v.number(),
},
v.string(),
),
v.optional(
v.object({
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
}),
),
]);
export const model = { k1: 'v1', k2: 2 };
v.record() 无固定键值,键值全部可动态添加(目前仅支持 key 为 string 类型):
record.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
o1: v.record(v.string(), v.string()),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { o1: { k1: 'v1' } };
以下类型会被解析为表单数组。
v.array() 定义会渲染为可动态增删的数组:
type-array.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
list: v.array(v.string()),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { list: ['v1'] };
v.tuple() 固定数组项,不可添加,超过长度自动过滤:
tuple.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
list: v.tuple([v.string()]),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { list: ['v1'] };
v.looseTuple() 固定数组项,不可添加,超过长度时保留:
loose-tuple.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
list: v.looseTuple([v.string()]),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { list: ['v1', 'v2'] };
v.tupleWithRest() 部分数组项固定,其余按指定类型可动态添加:
tuple-with-rest.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
list: v.tupleWithRest([v.string()], v.string()),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
export const model = { list: ['v1', 'v2'] };
v.optional() 的第二个参数即为默认值,渲染后直接填入表单:
default-value.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.optional(v.string(), 'default value'),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
使用 v.object() 可进行多级数据结构定义,自动嵌套渲染为子表单组:
nested-object.definition.ts
import * as v from 'valibot';
import { NFCSchema, setComponent } from '@piying/view-angular-core';
export const schema = v.object({
k1: v.string(),
o1: v.object({
k2: v.string(),
k3: v.string(),
}),
__helper: v.pipe(NFCSchema, setComponent('formHelper')),
});
更多类型请参考 Valibot API。自定义类型可使用 custom。
表单能力(值监听 / 布局移动 / 分区禁用 / 字段分组 / 验证 / 级联 / 过滤组 / 滚动组)见 表单使用。