十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
我们期望的场景是,

我的实现过程如下:
定义具体的数据返回值签名
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]
}        我们验证下
  公众号:萌萌哒草头将军
  
  
  
  loading...
  {{data.value}}
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]
}       验证如下:
  公众号:萌萌哒草头将军
  
  
  
  loading...
  {{data.value}}
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 }}
  
  
  
  loading...
  {{data.value}}
auto.gif
每次当我们改变参数时自动发送请求。