init: 整合项目(dashboard + www + docs)
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { inject, provide } from 'vue';
|
||||
|
||||
type ContextName = string | { name: string; key: string | symbol };
|
||||
|
||||
type ContextValue<T> = T extends (...args: any[]) => any ? ReturnType<T> : T;
|
||||
|
||||
type ContextProvider<T> = T extends (...args: any[]) => any ? T : (arg: T) => T;
|
||||
|
||||
type ContextConsumer<Context> = <N extends string | null | undefined = undefined>(
|
||||
consumerName?: N,
|
||||
defaultValue?: Context
|
||||
) => N extends null | undefined ? Context | null : Context;
|
||||
|
||||
/**
|
||||
* Creates a context provider and consumer pair.
|
||||
*
|
||||
* @param contextName - The name of the context. This can be a string or an object with a `name` and `key` property.
|
||||
* @param composable - An optional composable function that returns the context value. If not provided, the context value will be the first argument passed to the provider.
|
||||
*/
|
||||
export default function useContext<T>(
|
||||
contextName: ContextName,
|
||||
composable?: T extends (...args: any[]) => any ? T : never
|
||||
) {
|
||||
type Context = ContextValue<T>;
|
||||
|
||||
const name = typeof contextName === 'string' ? contextName : contextName.name;
|
||||
|
||||
const key = typeof contextName === 'string' ? Symbol(contextName) : contextName.key;
|
||||
|
||||
/**
|
||||
* Injects the context value.
|
||||
*
|
||||
* @param consumerName - The name of the component that is consuming the context. If provided, the component must be
|
||||
* used within the context provider.
|
||||
* @param defaultValue - The default value to return if the context is not provided.
|
||||
* @returns The context value.
|
||||
*/
|
||||
const useInject = (consumerName?: string | null, defaultValue?: any) => {
|
||||
const value = inject(key, defaultValue) ?? null;
|
||||
|
||||
if (consumerName != null && value === null) {
|
||||
throw new Error(`\`${consumerName}\` must be used within \`${name}\``);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
const useProvide = (...args: any[]) => {
|
||||
const value = composable?.(...args) ?? args[0];
|
||||
|
||||
provide(key, value);
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
return [useProvide, useInject] as [ContextProvider<T>, ContextConsumer<Context>];
|
||||
}
|
||||
Reference in New Issue
Block a user