Blame view

Yi.Vben5.Vue3/packages/@core/composables/src/use-priority-value.ts 2.58 KB
515fceeb   “wangming”   框架初始化
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
  import type { ComputedRef, Ref } from 'vue';
  
  import {
    getFirstNonNullOrUndefined,
    kebabToCamelCase,
  } from '@vben-core/shared/utils';
  import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
  
  /**
   * 依次从插槽、attrs、props、state 中获取值
   * @param key
   * @param props
   * @param state
   */
  export function usePriorityValue<
    T extends Record<string, any>,
    S extends Record<string, any>,
    K extends keyof T = keyof T,
  >(key: K, props: T, state: Readonly<Ref<NoInfer<S>>> | undefined) {
    const instance = getCurrentInstance();
    const slots = useSlots();
    const attrs = useAttrs() as T;
  
    const value = computed((): T[K] => {
      // props不管有没有传,都会有默认值,会影响这里的顺序,
      // 通过判断原始props是否有值来判断是否传入
      const rawProps = (instance?.vnode?.props || {}) as T;
  
      const standardRawProps = {} as T;
  
      for (const [key, value] of Object.entries(rawProps)) {
        standardRawProps[kebabToCamelCase(key) as K] = value;
      }
      const propsKey =
        standardRawProps?.[key] === undefined ? undefined : props[key];
  
      // slot可以关闭
      return getFirstNonNullOrUndefined(
        slots[key as string],
        attrs[key],
        propsKey,
        state?.value?.[key as keyof S],
      ) as T[K];
    });
  
    return value;
  }
  
  /**
   * 批量获取state中的值(每个值都是ref)
   * @param props
   * @param state
   */
  export function usePriorityValues<
    T extends Record<string, any>,
    S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,
  >(props: T, state: S | undefined) {
    const result: { [K in keyof T]: ComputedRef<T[K]> } = {} as never;
  
    (Object.keys(props) as (keyof T)[]).forEach((key) => {
      result[key] = usePriorityValue(key as keyof typeof props, props, state);
    });
  
    return result;
  }
  
  /**
   * 批量获取state中的值(集中在一个computed,用于透传)
   * @param props
   * @param state
   */
  export function useForwardPriorityValues<
    T extends Record<string, any>,
    S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,
  >(props: T, state: S | undefined) {
    const computedResult: { [K in keyof T]: ComputedRef<T[K]> } = {} as never;
  
    (Object.keys(props) as (keyof T)[]).forEach((key) => {
      computedResult[key] = usePriorityValue(
        key as keyof typeof props,
        props,
        state,
      );
    });
  
    return computed(() => {
      const unwrapResult: Record<string, any> = {};
      Object.keys(props).forEach((key) => {
        unwrapResult[key] = unref(computedResult[key]);
      });
      return unwrapResult as { [K in keyof T]: T[K] };
    });
  }