Valibot 配置表单
用一个 Valibot object schema 同时驱动 Plugin 配置、字段信息和 Web 表单。
给配置字段加标题、说明、控件偏好时,使用 valibot-form metadata。Plugin 仍只声明一份 Valibot schema,
Workbench 会自动显示配置表单;无需为普通配置另外编写 React 页面。
先给一个字段加标题
import { , , , } from '@pluxel/runtime'
@()
export class extends {
private readonly = this..(
.({
: .(.(.(), .({ : '启用服务' })), true),
}),
)
}构建并运行插件,标准配置页应出现“启用服务”开关,初始值为开启。
f.formMeta() 只描述显示方式;字段是否必填、默认值和有效范围仍由 Valibot 决定。
保存与运行时应用的区别见插件配置。
最小配置与渲染结果
下面是覆盖多种控件的完整参考例子。按需查找开关、分段选择、URL、整数、嵌套对象和列表; 无需在第一个 Plugin 中一次性采用全部控件。展开预览可直接操作表单,比较原始 Input 与校验后的 Output。
const = .({
: .(
.(
.(),
.({
: '启用示例服务',
: 'schema 默认值会进入 normalized config',
: { : 'runtime', : '运行时' },
}),
),
true,
),
: .(
.(
.(['development', 'production'] as ),
.({ : '运行环境', : 'runtime' }),
.({
: 'segmented',
: { : '开发', : '生产' },
}),
),
'development',
),
: .(
.(
.(),
.(),
.({
: '上游地址',
: 'URL 约束来自 schema;表单只负责编辑。',
: { : 'network', : '网络与重试' },
}),
.({ : 'https://api.example.com' }),
),
'https://api.example.com',
),
: .(
.(
.(),
.(),
.(1),
.(65535),
.({ : '监听端口', : 'network' }),
.({ : 1 }),
),
8787,
),
: .(
.(
.({
: .(
.(
.(),
.(),
.(1),
.(10),
.({ : '最大次数' }),
.({ : 1 }),
),
3,
),
: .(
.(
.(),
.(),
.(100),
.({ : '退避时间(毫秒)' }),
.({ : 100 }),
),
250,
),
}),
.({ : '重试策略', : 'network' }),
.({ : 'card', : 2 }),
),
{
: 3,
: 250,
},
),
: .(
.(
.(.(.(), .())),
.({ : '允许的 Origin', : 'network' }),
.({
: 'list',
: 'Origin',
: '添加 Origin',
: 'https://api.example.com',
}),
),
['https://api.example.com'],
),
})
@({ : 'Example' })
export class extends {
private readonly = this..()
override () {
(this.., { : this.. })
}
}配置渲染预览 · 表单、Input 与 Output
当字段既有默认值又有表单 metadata 时,让 v.optional() 包住完成后的 v.pipe():v.optional(v.pipe(base, constraints, metadata), default)。这样默认值属于外层可选语义,字段 extractor 解包 optional 后仍能读取内层 metadata;不要写成 v.pipe(v.optional(base, default), metadata)。
注意:configs.use() 要放在 Plugin class 的普通顶层 field;不要在 constructor 读取 config,不要使用 #private,每个具体 Plugin 只声明一个 object schema。
metadata 做什么
valibot-form 的 core entry 不依赖 React/Mantine,适合 runtime config、CLI prompt、配置文件编辑器和 schema inspection:
import * as from 'valibot'
import * as from 'valibot-form'
const = .({
: .(
.(['development', 'production'] as ),
.({ : '运行环境' }),
.({
: 'segmented',
: { : '开发', : '生产' },
}),
),
})
const = .()常用映射:
| Valibot schema | metadata | 默认 web 控件 |
|---|---|---|
v.string() | stringMeta | TextInput |
v.number() | numberMeta | NumberInput |
v.boolean() | — | Switch |
v.picklist() | picklistMeta | Select |
v.array() | arrayMeta | List |
v.record() | recordMeta | Table |
v.object() | objectMeta | Card/stack |
v.variant() / union | unionMeta | Select/segmented |
类型入口
类型直接从 package 源码导出。下面的示例由 Twoslash 对当前 workspace 类型检查,不在文档中维护另一份类型声明:
import type { FormMeta, } from 'valibot-form'
import type { } from 'valibot-form/web'
type MetadataKeys = keyof FormMeta
type FormProps = keyof <>formMeta() 的 title / description 使用 Valibot 标准 metadata,help、section、layout、disabled、readOnly 和 hidden
仍是表单展示偏好;类型对应的 *Meta() 只负责控件偏好。requiredness、选项、格式和范围仍来自 Valibot schema,例如
v.optional()、v.url()、v.minValue()、v.maxValue() 和 v.integer()。原生 v.title()、v.description() 与
v.metadata({ title, description }) 也会按 pipe 顺序互操作,但标准示例使用一次 formMeta() 集中声明。
需要编辑 schema 或查看类型补全时,打开独立的配置 Playground。
Web adapter
只有在自己的 React 应用中需要自动表单,才从 valibot-form/web 导入。标准 Workbench 配置页已包含它。
独立应用需要安装 React、Mantine、TanStack Form、Tabler Icons 和 dnd-kit:
npx nypm add valibot-form valibot react react-dom @mantine/core @mantine/hooks @tanstack/react-form @tabler/icons-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
export function () {
return (
<>
<
={}
={{
: { : 'development' },
: async ({ }) => (),
}}
>
<. />
<.>
{({ , , , , }) => (
<>
< ="button" ={() => ()} ={! || }>
重置
</>
< ="button" ={} ={! || }>
保存
</>
</>
)}
</.>
</>
</>
)
}上例是独立 React 应用,因此自行导入 Mantine CSS。放进 Workbench View 时,仍需自己的 MantineProvider,
但应删除 @mantine/core/styles.css 导入,基础 CSS 已由宿主加载;见页面资源参考。
AutoForm 负责根据 schema metadata 规划和渲染字段;配置 authority 仍然是 runtime 的 configs.use() 校验流程。把表单值送回 host API 前,服务端必须再次用同一个 schema 校验,不能把浏览器表单当作信任边界。
与 Pluxel 配置界面的边界
valibot-form 提供 schema metadata、字段提取和可选 Web adapter,不提供 Pluxel Plugin 发现、配置传输或持久化 API。自定义配置界面应直接接收 browser-safe 的 schema,并通过应用自己的服务端接口提交修改;服务端继续使用同一 schema 校验输入。
Pluxel Workbench 内置的 Plugin 配置页由宿主读取 runtime config metadata。Plugin 作者只声明 this.configs.use(Config),不调用 Workbench 内部的 schema projection 或配置 patch 实现。
检查清单
- schema 是 object 或 intersect,适合
AutoForm。 - 默认值写在
v.optional(v.pipe(...metadata), default),没有业务 fallback,也不会在解包 optional 时丢失 metadata。 configs.use()是 class 顶层普通 field,且 Plugin 只有一个 config field。- server runtime 是最终校验者;browser 表单只提供编辑体验。
- core 工具需要 schema 时只 import
valibot-form,不把 React/Mantine 带入 server bundle。
最后更新于