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, S extends Record, K extends keyof T = keyof T, >(key: K, props: T, state: Readonly>> | 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; }