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

94 lines
2.6 KiB
TypeScript
Raw Normal View History

import type { ComputedRef, Ref } from 'vue';
import { computed, getCurrentInstance, unref, useAttrs, useSlots } from 'vue';
import {
getFirstNonNullOrUndefined,
kebabToCamelCase,
} from '@vben-core/shared/utils';
/**
* attrspropsstate
* @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;
for (const [key, value] of Object.entries(rawProps)) {
2024-08-26 02:02:09 +00:00
standardRawProps[kebabToCamelCase(key) as K] = value;
}
const propsKey =
2024-08-26 02:02:09 +00:00
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;
}
/**
* stateref
* @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;
}
/**
* statecomputed
* @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] };
});
}