Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into antdv-next

This commit is contained in:
dap
2026-03-16 20:33:39 +08:00
358 changed files with 3665 additions and 2339 deletions

View File

@@ -75,19 +75,16 @@ export class FormApi {
const defaultState = getDefaultState();
this.store = new Store<VbenFormProps>(
{
...defaultState,
...storeState,
},
{
onUpdate: () => {
this.prevState = this.state;
this.state = this.store.state;
this.updateState();
},
},
);
this.store = new Store<VbenFormProps>({
...defaultState,
...storeState,
});
this.store.subscribe((state) => {
this.prevState = this.state;
this.state = state;
this.updateState();
});
this.state = this.store.state;
this.stateHandler = new StateHandler();

View File

@@ -36,9 +36,11 @@ export default function useDependencies(
const values = useFormValues();
const formRenderProps = injectRenderFormProps();
const formApi = formRenderProps.form;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const formApi = formRenderProps.form!;
if (!formApi) {
throw new Error('Form api is required in useDependencies');
}
if (!values) {
throw new Error('useDependencies should be used within <VbenForm>');
@@ -123,7 +125,7 @@ export default function useDependencies(
}
if (isFunction(trigger)) {
await trigger(formValues, formApi);
trigger(formValues, formApi);
}
},
{ deep: true, immediate: true },

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ZodType } from 'zod';
import type { FormSchema, MaybeComponentProps } from '../types';
import type { FormActions, FormSchema, MaybeComponentProps } from '../types';
import { computed, nextTick, onUnmounted, useTemplateRef, watch } from 'vue';
@@ -63,10 +63,16 @@ const formApi = formRenderProps.form;
const compact = computed(() => formRenderProps.compact);
const isInValid = computed(() => errors.value?.length > 0);
function getFormApi(): FormActions {
if (!formApi) {
throw new Error('Form api is required in <FormField />');
}
return formApi;
}
const FieldComponent = computed(() => {
const finalComponent = isString(component)
? componentMap.value[component]
: component;
const finalComponent = isString(component) ? componentMap.value[component] : component;
if (!finalComponent) {
// 组件未注册
console.warn(`Component ${component} is not registered`);
@@ -74,14 +80,8 @@ const FieldComponent = computed(() => {
return finalComponent;
});
const {
dynamicComponentProps,
dynamicRules,
isDisabled,
isIf,
isRequired,
isShow,
} = useDependencies(() => dependencies);
const { dynamicComponentProps, dynamicRules, isDisabled, isIf, isRequired, isShow } =
useDependencies(() => dependencies);
const labelStyle = computed(() => {
return labelClass?.includes('w-') || isVertical.value
@@ -156,7 +156,7 @@ const fieldRules = computed(() => {
const computedProps = computed(() => {
const finalComponentProps = isFunction(componentProps)
? componentProps(values.value, formApi!)
? componentProps(values.value, getFormApi())
: componentProps;
return {
@@ -186,7 +186,7 @@ const customContentRender = computed(() => {
if (!isFunction(renderComponentContent)) {
return {};
}
return renderComponentContent(values.value, formApi!);
return renderComponentContent(values.value, getFormApi());
});
const renderContentKey = computed(() => {
@@ -208,8 +208,7 @@ function fieldBindEvent(slotProps: Record<string, any>) {
const handler = slotProps.componentField['onUpdate:modelValue'];
const bindEventField =
modelPropName ||
(isString(component) ? componentBindEventMap.value?.[component] : null);
modelPropName || (isString(component) ? componentBindEventMap.value?.[component] : null);
let value = modelValue;
// antd design 的一些组件会传递一个 event 对象
@@ -283,12 +282,7 @@ onUnmounted(() => {
</script>
<template>
<FormField
v-if="!hide && isIf"
v-bind="fieldProps"
v-slot="slotProps"
:name="fieldName"
>
<FormField v-if="!hide && isIf" v-bind="fieldProps" v-slot="slotProps" :name="fieldName">
<FormItem
v-show="isShow"
:class="{
@@ -308,7 +302,7 @@ onUnmounted(() => {
cn(
'flex leading-6',
{
'mr-2 flex-shrink-0 justify-end': !isVertical,
'mr-2 shrink-0 justify-end': !isVertical,
'mb-1 flex-row': isVertical,
},
labelClass,
@@ -346,11 +340,7 @@ onUnmounted(() => {
v-bind="createComponentProps(slotProps)"
:disabled="shouldDisabled"
>
<template
v-for="name in renderContentKey"
:key="name"
#[name]="renderSlotProps"
>
<template v-for="name in renderContentKey" :key="name" #[name]="renderSlotProps">
<VbenRenderContent
:content="customContentRender[name]"
v-bind="{ ...renderSlotProps, formContext: slotProps }"
@@ -358,11 +348,7 @@ onUnmounted(() => {
</template>
<!-- <slot></slot> -->
</component>
<VbenTooltip
v-if="compact && isInValid"
:delay-duration="300"
side="left"
>
<VbenTooltip v-if="compact && isInValid" :delay-duration="300" side="left">
<template #trigger>
<slot name="trigger">
<CircleAlert

View File

@@ -17,7 +17,7 @@ const props = defineProps<Props>();
<template>
<FormLabel :class="cn('flex items-center', props.class)">
<span v-if="required" class="mr-[2px] text-destructive">*</span>
<span v-if="required" class="mr-0.5 text-destructive">*</span>
<slot></slot>
<VbenHelpTooltip v-if="help" trigger-class="size-3.5 ml-1">
<!-- 可通过\n换行 -->
@@ -26,6 +26,6 @@ const props = defineProps<Props>();
</span>
<!-- <VbenRenderContent :content="help" /> -->
</VbenHelpTooltip>
<span v-if="colon && label" class="ml-[2px]">:</span>
<span v-if="colon && label" class="ml-0.5">:</span>
</FormLabel>
</template>

View File

@@ -157,7 +157,7 @@ const computedSchema = computed(
...schema.formFieldProps,
},
formItemClass: cn(
'flex-shrink-0',
'shrink-0',
{ hidden },
formItemClass,
resolvedSchemaFormItemClass,