2024-09-10 13:48:51 +00:00
|
|
|
|
import type { ComputedRef, Ref } from 'vue';
|
|
|
|
|
import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
|
2024-08-25 15:40:52 +00:00
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
getFirstNonNullOrUndefined,
|
|
|
|
|
kebabToCamelCase,
|
2024-09-10 13:48:51 +00:00
|
|
|
|
} from '@vben-core/shared/utils';
|
2024-08-25 15:40:52 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 依次从插槽、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;
|
|
|
|
|
|
2024-08-26 02:02:09 +00:00
|
|
|
|
const standardRawProps = {} as T;
|
2024-08-25 15:40:52 +00:00
|
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(rawProps)) {
|
2024-08-26 02:02:09 +00:00
|
|
|
|
standardRawProps[kebabToCamelCase(key) as K] = value;
|
2024-08-25 15:40:52 +00:00
|
|
|
|
}
|
|
|
|
|
const propsKey =
|
2024-08-26 02:02:09 +00:00
|
|
|
|
standardRawProps?.[key] === undefined ? undefined : props[key];
|
2024-08-25 15:40:52 +00:00
|
|
|
|
|
|
|
|
|
// slot可以关闭
|
|
|
|
|
return getFirstNonNullOrUndefined(
|
|
|
|
|
slots[key as string],
|
|
|
|
|
attrs[key],
|
|
|
|
|
propsKey,
|
|
|
|
|
state?.value?.[key as keyof S],
|
|
|
|
|
) as T[K];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2024-09-10 13:48:51 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 批量获取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] };
|
|
|
|
|
});
|
|
|
|
|
}
|