- 初始化一个请求函数,然后根据初始参数,立即发送请求
- 返回请求结果,并且返回请求回调函数,方便我们根据新的参数再次调用
- 要求返回值包含加载中状态,错误信息以及正常的数据类型。
我的实现过程如下:
定义具体的数据返回值签名
interface Fetch {
loading: boolean,
value?: T, // 具体的返回类型是泛型
error?: string
}
完整的签名如下
export declare function useFetch (
fn: (args: Params) => Promise,
initParams: Params
): [Fetch, (params: Params) => Promise]
函数实现如下:
export const useFetch = (
fn: (args: Params) => Promise,
initParams: Params
): [Fetch, (params: Params) => Promise] => {
// 定义基础的数据格式
const data = reactive>({
loading: true,
value: undefined,
error: undefined
}) as Fetch // 这里会报错:T类型无法赋值给UnwrapRef类型
// 我不懂为啥,UnwrapRef是vue的深层响应式类型的声明
// 这里导致我无法默认的类型赋值,不符合直觉,可能是我ts太菜了
// 懂的大佬评论区带带我吧
// 定义请求回调
const callback = (params: Params): Promise => new Promise((resolve, reject) => {
data.loading = true
fn(params)
.then(result => {
data.value = result as any
resolve(result)
})
.catch(error => {
data.error = error
reject(error)
})
.finally(() => data.loading = false)
})
// 立即执行
watchSyncEffect(() => {
callback(initParams)
})
return [data, callback]
}
我们验证下
公众号:萌萌哒草头将军
fetch.gif
页面刷新后立即发出请求了!
🚀 手动请求函数
我们期望的场景是,
- 初始化一个请求函数
- 返回请求回调函数,方便我们调用
- 要求返回值包含加载中状态,错误信息以及正常的数据类型
这个的实现和上面类似,我们不需要初始参数和类型,也不用立即执行,
完整的签名如下
export declare function useFetch (
fn: (args: unknown) => Promise
): [Fetch, (params: unknown) => Promise]
实现如下:
export const useFetchFn = (
fn: (args: unknown) => Promise
): [Fetch, (params: unknown) => Promise] => {
const data = reactive>({
loading: false, // 默认为false
value: undefined,
error: undefined
}) as Fetch
const callback = (params: unknown): Promise => new Promise((resolve, reject) => {
data.loading = true
fn(params)
.then(result => {
data.value = result as any
resolve(result)
})
.catch(error => {
data.error = error
reject(error)
})
.finally(() => data.loading = false)
})
return [data, callback]
}
验证如下:
公众号:萌萌哒草头将军
fetchfn.gif
页面刷新后没有发出请求,点击按钮之后才发出请求!
🚀 自动请求函数
我们期望的场景是,
- 初始化一个请求函数,然后根据初始参数,立即发送请求
- 当参数发生变化时,自动根据最新参数发送请求
- 要求返回值包含加载中状态,错误信息以及正常的数据类型。
这个的实现和立即请求函数类似,只需要监听参数的变化,
完整的签名如下
export declare function useFetch (
fn: (args: Params) => Promise,
initParams: Params
): Fetch
实现如下:
export const useAutoFetch = (
fn: (args: Params) => Promise,
initParams: Params
): Fetch => {
const data = reactive>({
loading: true,
value: undefined,
error: undefined
}) as Fetch
const callback = (params: Params): Promise => new Promise((resolve, reject) => {
data.loading = true
fn(params)
.then(result => {
data.value = result as any
resolve(result)
})
.catch(error => {
data.error = error
reject(error)
})
.finally(() => data.loading = false)
})
// 如果不需要立即执行,可没有这步
const effects = watchSyncEffect(() => {
callback(initParams)
})
// 自动监听参数变化
const effects = watch([initParams], () => callback(initParams))
// 卸载页面时,关闭监听
onUnmounted(() => effects())
return data
}
我们验证下功能
公众号:萌萌哒草头将军
{{ params.age }}
auto.gif
每次当我们改变参数时自动发送请求。