fix(@vben-core/form-ui): restore lock screen form submission (#8195)

* fix(@vben-core/form-ui): avoid stale form context access

* fix(@vben/playground): constrain date range codec fields

* test(@vben-core/form-ui): harden benchmark fixtures

* docs(@vben/docs): document form runtime and benchmarks

* fix(@vben/docs): 明确 getValues/submit 返回值及 submit 参数类型
This commit is contained in:
dream-weave
2026-07-24 10:05:27 +08:00
committed by GitHub
parent 0542b509ca
commit dcdbfe5dfc
13 changed files with 195 additions and 86 deletions

View File

@@ -17,6 +17,37 @@ const codec = createDateRangeCodec<SearchFormValues>()({
});
describe('date range codec', () => {
it('only accepts optional date range fields', () => {
interface RangeFieldCandidates extends Record<string, unknown> {
optionalRange?: [Dayjs, Dayjs];
optionalText?: string;
requiredRange: [Dayjs, Dayjs];
}
const createCodec = createDateRangeCodec<RangeFieldCandidates>();
const optionalRangeCodec = createCodec({
endField: 'end',
rangeField: 'optionalRange',
startField: 'start',
});
expect(optionalRangeCodec).toEqual({
decode: expect.any(Function),
encode: expect.any(Function),
});
createCodec({
endField: 'end',
// @ts-expect-error A required range cannot be omitted by decode.
rangeField: 'requiredRange',
startField: 'start',
});
createCodec({
endField: 'end',
// @ts-expect-error The range field must contain a DateRange.
rangeField: 'optionalText',
startField: 'start',
});
});
it('encodes and decodes configurable date range fields', () => {
const submitValues = codec.encode({
createdAt: [dayjs('2026-07-01'), dayjs('2026-07-23')],

View File

@@ -4,6 +4,18 @@ import dayjs from 'dayjs';
type DateRange = [Dayjs, Dayjs];
type OptionalDateRangeField<
TFormValues extends Record<string, unknown>,
TRangeField extends keyof TFormValues,
> =
Record<never, never> extends Pick<TFormValues, TRangeField>
? [Exclude<TFormValues[TRangeField], undefined>] extends [never]
? never
: Exclude<TFormValues[TRangeField], undefined> extends DateRange
? TRangeField
: never
: never;
type DateRangeSubmitValues<
TFormValues extends Record<string, unknown>,
TRangeField extends keyof TFormValues,
@@ -19,7 +31,7 @@ interface DateRangeCodecOptions<
TEndField extends string,
> {
endField: TEndField;
rangeField: TRangeField;
rangeField: OptionalDateRangeField<TFormValues, TRangeField> & TRangeField;
startField: TStartField;
}
@@ -30,11 +42,16 @@ export function createDateRangeCodec<
TRangeField extends keyof TFormValues & string,
TStartField extends string,
TEndField extends string,
>({
endField,
rangeField,
startField,
}: DateRangeCodecOptions<TFormValues, TRangeField, TStartField, TEndField>) {
>(
options: DateRangeCodecOptions<
TFormValues,
TRangeField,
TStartField,
TEndField
>,
) {
const { endField, startField } = options;
const rangeField = options.rangeField as TRangeField;
type SubmitValues = DateRangeSubmitValues<
TFormValues,
TRangeField,

View File

@@ -132,7 +132,8 @@ function handleValuesChange(
}
async function syncPreviewValues(values?: Readonly<ValueFormatFormValues>) {
liveValues.value = { ...(values ?? formApi.form?.values) };
const rawValues = values ?? (await formApi.getRawValues());
liveValues.value = { ...rawValues };
transformedValues.value = await formApi.getValues();
}
@@ -151,7 +152,7 @@ onMounted(async () => {
<template #description>
<div class="text-muted-foreground space-y-2">
<p>
<code>form.values</code> 保持组件原始值<code>getValues()</code> /
<code>getRawValues()</code> 返回组件原始值<code>getValues()</code> /
提交时会按 <code>codec.encode</code> 输出 payload回填时通过
<code>codec.decode</code> 恢复组件值
</p>
@@ -179,7 +180,7 @@ onMounted(async () => {
</Card>
<div class="grid gap-4 lg:grid-cols-2">
<Card title="原始 form.values(组件值)">
<Card title="getRawValues() 输出(组件值)">
<pre class="bg-muted overflow-auto rounded-md p-4 text-sm">{{
liveValuesPreview
}}</pre>