refactor(@vben-core/form-ui): migrate to Zod 4 and TanStack Form (#8176)

* build(@vben-core/form-ui): update form validation dependencies

* refactor(@vben-core/form-ui): replace vee-validate with TanStack Form

* test(@vben-core/form-ui): cover TanStack Form migration

* docs(@vben/docs): document Zod 4 form migration

* refactor(project): update form adapters

* refactor(project): migrate application form consumers

* refactor(@vben/playground): migrate form examples

* docs(@vben/docs): fix validate return type and required rule empty check in form docs

* fix(@vben-core/form-ui): resolve oxlint and eslint errors

- rewrite nested ternary expressions as if/else in form-field-array.vue and form-runtime.ts
- sort @tanstack/vue-form before @vben-core/composables in package.json

* chore: fix merge artifacts and formatting

- move dependencies before devDependencies in root package.json
- update preferences snapshot for widget positioning fields
- format form-array demo README

* refactor(@vben-core/form-ui): optimize form runtime and value flow

- add fine-grained field selectors and atomic dependency resolution
- expose raw and formatted value snapshots with focused regression coverage

* fix(@vben/layouts): dispose sortable instance on unmount

* docs(@vben/docs): document form runtime API changes

- list added, changed, removed, and deprecated form APIs
- document atomic dependencies and raw versus formatted values
This commit is contained in:
dream-weave
2026-07-22 19:47:07 +08:00
committed by GitHub
parent 6b6708bcf2
commit 28757fb9c8
81 changed files with 4683 additions and 1435 deletions

View File

@@ -1,6 +1,7 @@
import type {
VbenFormProps as FormProps,
VbenFormSchema as FormSchema,
FormValues,
} from '@vben/common-ui';
import type { ComponentPropsMap, ComponentType } from './component';
@@ -16,7 +17,7 @@ async function initSetupVbenForm() {
CheckboxGroup: 'model-value',
},
},
defineRules: {
rules: {
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
@@ -33,9 +34,18 @@ async function initSetupVbenForm() {
});
}
const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
function useVbenForm<TValues extends FormValues = FormValues>(
options: FormProps<ComponentType, ComponentPropsMap, TValues>,
) {
return useForm<TValues, ComponentType, ComponentPropsMap>(options);
}
export { initSetupVbenForm, useVbenForm, z };
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;
export type VbenFormSchema<TValues extends FormValues = FormValues> =
FormSchema<ComponentType, ComponentPropsMap, TValues>;
export type VbenFormProps<TValues extends FormValues = FormValues> = FormProps<
ComponentType,
ComponentPropsMap,
TValues
>;

View File

@@ -46,7 +46,7 @@ const formSchema = computed((): VbenFormSchema[] => {
rules(values) {
const { password } = values;
return z
.string({ required_error: $t('authentication.passwordTip') })
.string({ error: $t('authentication.passwordTip') })
.min(1, { message: $t('authentication.passwordTip') })
.refine((value) => value === password, {
message: $t('authentication.confirmPasswordTip'),

View File

@@ -38,7 +38,7 @@ const formSchema = computed((): VbenFormSchema[] => {
rules(values) {
const { newPassword } = values;
return z
.string({ required_error: '请再次输入新密码' })
.string({ error: '请再次输入新密码' })
.min(1, { message: '请再次输入新密码' })
.refine((value) => value === newPassword, {
message: '两次输入的密码不一致',