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

@@ -56,12 +56,13 @@ const schema: VbenFormSchema[] = [
async (value: string) => {
return !(await isMenuNameExists(value, formData.value?.id));
},
(value) => ({
message: $t('ui.formRules.alreadyExists', [
$t('system.menu.menuName'),
value,
]),
}),
{
error: (issue) =>
$t('ui.formRules.alreadyExists', [
$t('system.menu.menuName'),
issue.input,
]),
},
),
},
{
@@ -139,12 +140,13 @@ const schema: VbenFormSchema[] = [
async (value: string) => {
return !(await isMenuPathExists(value, formData.value?.id));
},
(value) => ({
message: $t('ui.formRules.alreadyExists', [
$t('system.menu.path'),
value,
]),
}),
{
error: (issue) =>
$t('ui.formRules.alreadyExists', [
$t('system.menu.path'),
issue.input,
]),
},
),
},
{
@@ -227,7 +229,7 @@ const schema: VbenFormSchema[] = [
},
fieldName: 'linkSrc',
label: $t('system.menu.linkSrc'),
rules: z.string().url($t('ui.formRules.invalidURL')),
rules: z.url($t('ui.formRules.invalidURL')),
},
{
component: 'Input',
@@ -278,18 +280,18 @@ const schema: VbenFormSchema[] = [
},
{
component: 'Input',
componentProps: (values) => {
return {
allowClear: true,
class: 'w-full',
disabled: values.meta?.badgeType !== 'normal',
};
},
dependencies: {
show: (values) => {
return values.type !== 'button';
resolve: ({ values }) => {
return {
componentProps: {
allowClear: true,
class: 'w-full',
disabled: values.meta?.badgeType !== 'normal',
},
show: values.type !== 'button',
};
},
triggerFields: ['type'],
triggerFields: ['meta.badgeType', 'type'],
},
fieldName: 'meta.badge',
label: $t('system.menu.badge'),
@@ -451,7 +453,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
? $t(formData.value.meta.title)
: '';
} else {
formApi.resetForm();
formApi.reset();
titleSuffix.value = '';
}
}