provide/inject是vue中实现父组件与后代组件共享数据的方式,但是在typescript中直接使用provide/inject,会丢失共享的数据类型。如下所示:
父组件中使用
子组件中使用
这里分享一个自定义方法,实现provide/inject类型声明
首先通过一个工具函数封装provide和inject
返回值解构出来的createProjectInfo
和useProjectInfo
相当于封装了我们指定业务数据的provide/inject
父组件中使用
子组件中使用
可以看到使用useProjectInfo就能够返回我们需要的数据的类型
createContextHook使用说明
createContextHook(key, func)
- 函数接收key,func两个入参,返回 {createXxx, useXxx}对象
- 第一个参数Key,同provide/inject一样,且作为返回值中Xxx的对应的命名
- 第二个参数func,其返回结果作为provide的第二个参数,inject的返回值
- createXxx其实就是包装func,并func的返回值存入provide中
- useXxx就是对inject(key)的包装
这种方式可以使我们共享数据的定义非常灵活,且充分利用了ts类型推导的能力,不用手动去声明类型了
createContextHook源码
export function createContextHook<
TKey extends Capitalize<string>,
TCreateFunc extends (...args: any) => any
>(key: TKey, createFunc: TCreateFunc) {
const symbolKey = Symbol(key);
function create(...args: any[]) {
const obj = createFunc(...args);
provide(symbolKey, obj);
return obj;
}
function use() {
return inject(symbolKey);
}
return {
[`create${key}`]: create,
[`use${key}`]: use,
} as {
[name in `create${TKey}`]: TCreateFunc;
} & {
[name in `use${TKey}`]: () => ReturnType<TCreateFunc>;
};
}
可以看到源码其实很简单,主要是运用了typescript的类型声明的一些能力
感兴趣的小伙伴,可以自己试一试,希望本文对你在ts中使用provide/inject有所帮助!