123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import type { ComputedRef, Ref } from 'vue';
- import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
- import {
- getFirstNonNullOrUndefined,
- kebabToCamelCase,
- } from '@vben-core/shared/utils';
- /**
- * 依次从插槽、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] };
- });
- }
|