gaoluyang
2026-06-24 c0cb161bb52ce0fbdce5c66ec391d107c75e2452
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import type {
  ExtendedFormApi,
  FormItemDependencies,
  FormSchemaRuleType,
  MaybeComponentProps,
} from '../types';
 
import { computed, isRef, ref, watch } from 'vue';
 
import { get, isBoolean, isFunction } from '..\..\..\..\base\shared\src\utils';
 
import { useFormValues } from 'vee-validate';
 
import { resolveFieldNamePath } from '../field-name';
import { injectFormProps } from '../use-form-context';
import { injectRenderFormProps } from './context';
 
/**
 * 解析Nested Objects对应的字段值
 * @param values 表单值
 * @param fieldName 字段名
 */
function resolveValueByFieldName(
  values: Record<string, any>,
  fieldName: string,
) {
  // vee-validate:[] 表示禁用嵌套
  const { rawKey } = resolveFieldNamePath(fieldName);
  if (rawKey) {
    return values[rawKey];
  }
 
  return get(values, fieldName);
}
export default function useDependencies(
  getDependencies: () => FormItemDependencies | undefined,
) {
  const values = useFormValues();
 
  const [extendApi] = injectFormProps();
  const formRenderProps = injectRenderFormProps();
 
  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>');
  }
 
  // 在 dependencies 里提供访问extendApi的能力
  const getController = (): ExtendedFormApi => {
    const controller = isRef(extendApi)
      ? extendApi.value.formApi
      : extendApi.formApi;
 
    if (!controller) {
      throw new Error('formApi is required in useDependencies');
    }
 
    return controller;
  };
 
  const isIf = ref(true);
  const isDisabled = ref(false);
  const isShow = ref(true);
  const isRequired = ref(false);
  const dynamicComponentProps = ref<MaybeComponentProps>({});
  const dynamicRules = ref<FormSchemaRuleType>();
 
  const triggerFieldValues = computed(() => {
    // 该字段可能会被多个字段触发
    const triggerFields = getDependencies()?.triggerFields ?? [];
    return triggerFields.map((dep) => {
      return resolveValueByFieldName(values.value, dep);
    });
  });
 
  const resetConditionState = () => {
    isDisabled.value = false;
    isIf.value = true;
    isShow.value = true;
    isRequired.value = false;
    dynamicRules.value = undefined;
    dynamicComponentProps.value = {};
  };
 
  watch(
    [triggerFieldValues, getDependencies],
    async ([_values, dependencies]) => {
      if (!dependencies || !dependencies?.triggerFields?.length) {
        return;
      }
      resetConditionState();
      const {
        componentProps,
        disabled,
        if: whenIf,
        required,
        rules,
        show,
        trigger,
      } = dependencies;
 
      // 1. 优先判断if,如果if为false,则不渲染dom,后续判断也不再执行
      const formValues = values.value;
 
      if (isFunction(whenIf)) {
        isIf.value = !!(await whenIf(formValues, formApi, getController()));
        // 不渲染
        if (!isIf.value) return;
      } else if (isBoolean(whenIf)) {
        isIf.value = whenIf;
        if (!isIf.value) return;
      }
 
      // 2. 判断show,如果show为false,则隐藏
      if (isFunction(show)) {
        isShow.value = !!(await show(formValues, formApi, getController()));
      } else if (isBoolean(show)) {
        isShow.value = show;
      }
 
      if (isFunction(componentProps)) {
        dynamicComponentProps.value = await componentProps(
          formValues,
          formApi,
          getController(),
        );
      }
 
      if (isFunction(rules)) {
        dynamicRules.value = await rules(formValues, formApi, getController());
      }
 
      if (isFunction(disabled)) {
        isDisabled.value = !!(await disabled(
          formValues,
          formApi,
          getController(),
        ));
      } else if (isBoolean(disabled)) {
        isDisabled.value = disabled;
      }
 
      if (isFunction(required)) {
        isRequired.value = !!(await required(
          formValues,
          formApi,
          getController(),
        ));
      }
 
      if (isFunction(trigger)) {
        await trigger(formValues, formApi, getController());
      }
    },
    { deep: true, immediate: true },
  );
 
  return {
    dynamicComponentProps,
    dynamicRules,
    isDisabled,
    isIf,
    isRequired,
    isShow,
  };
}