interface Test {
firstName: string;
}
const form = useForm<Test>({
defaultValues: {
firstName: "default",
},
onSubmit: async ({ value }) => {
console.log(value);
},
});
<form.Field
name="firstName"
//...
/>
firstName
为name
,那么至少需要修改三次,这极大的增加了代码的不稳定性const define = v.object({ firstName: v.optional(v.string(), "default") });
type Define=v.InferOutput<typeof define>
// 等价于
type Define = {
v1: string;
};
schema
定义layout
方法可以将任何控件移动到可以存在子级的 schema 中v.intersect([
v.pipe(v.object({}), setAlias("scope1")),
v.object({
key1: v.pipe(
v.object({
test1: v.pipe(v.optional(v.string(), "value1"), layout({ keyPath: ["#", "@scope1"] })),
}),
),
}),
]);
object
的字段顺序,则可以参照 MDNv.pipe(v.number(), v.title("k2-label"), setWrappers(["label"]));
虽然包装器也可以用于控件组,但是直接自定义会更方便些
v.pipe(
v.object({
k1: v.pipe(v.string(), v.title("k1-label"), setWrappers(["label"])),
k2: v.pipe(v.number(), v.title("k2-label"), v.minValue(10), setWrappers(["label", "validator"])),
}),
setComponent("fieldset"),
);
Angular
,Vue
,React
,Svelte
,Solid
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.