48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
import type { Ref } from 'vue';
|
||
import { computed, getCurrentInstance, useAttrs, useSlots } from 'vue';
|
||
|
||
import {
|
||
getFirstNonNullOrUndefined,
|
||
kebabToCamelCase,
|
||
} from '@vben-core/shared';
|
||
|
||
/**
|
||
* 依次从插槽、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;
|
||
}
|