admin-vben/packages/@core/composables/src/use-priority-value.ts

94 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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] };
});
}