成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Vue3使用hook封裝常見的幾種異步請求函數場景,讓開發更絲滑

開發 前端
初始化一個請求函數,然后根據初始參數,立即發送請求,返回請求結果,并且返回請求回調函數,方便我們根據新的參數再次調用。

?? 立即請求函數

我們期望的場景是,

  • 初始化一個請求函數,然后根據初始參數,立即發送請求
  • 返回請求結果,并且返回請求回調函數,方便我們根據新的參數再次調用
  • 要求返回值包含加載中狀態,錯誤信息以及正常的數據類型。

我的實現過程如下:

定義具體的數據返回值簽名

interface Fetch<T> {
  loading: boolean,
  value?: T, // 具體的返回類型是泛型
  error?: string
}

完整的簽名如下

export declare function useFetch <T, Params>(
  fn: (args: Params) => Promise<T>,
  initParams: Params  
): [Fetch<T>, (params: Params) => Promise<unknown>]

函數實現如下:

export const useFetch = <T, Params>(
  fn: (args: Params) => Promise<T>,
  initParams: Params  
): [Fetch<T>, (params: Params) => Promise<T>] => {
  
  // 定義基礎的數據格式
  const data = reactive<Fetch<T>>({
    loading: true,
    value: undefined,
    error: undefined
  }) as Fetch<T> // 這里會報錯:T類型無法賦值給UnwrapRef<T>類型
  // 我不懂為啥,UnwrapRef是vue的深層響應式類型的聲明
  // 這里導致我無法默認的類型賦值,不符合直覺,可能是我ts太菜了
  // 懂的大佬評論區帶帶我吧
  
  // 定義請求回調
  const callback = (params: Params): Promise<T> => 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]
}

我們驗證下

<script setup lang="ts">
import { reactive } from 'vue';
import { useFetch } from './hooks/index';

const fn = () => new Promise((resolve) => {
  setTimeout(()=> resolve({data: [], msg: '', code: 200}), 1000)
})

const [data, fetch] = useFetch<unknown, object>(fn, {})

</script>

<template>
  <h4>公眾號:萌萌噠草頭將軍</h4>

  <!-- 加載中時用css禁用按鈕 -->
  <button
    :style="{'pointer-events': data.loading ? 'none' : 'auto'}"
    @click="fetch({})"
  >{{ data.loading ? 'laoding...' : 'fetch' }}</button>
  
  <h1 v-if="data.loading">loading...</h1>
  <h1 v-else>{{data.value}}</h1>
</template>

fetch.giffetch.gif

頁面刷新后立即發出請求了!

?? 手動請求函數

我們期望的場景是,

  • 初始化一個請求函數
  • 返回請求回調函數,方便我們調用
  • 要求返回值包含加載中狀態,錯誤信息以及正常的數據類型

這個的實現和上面類似,我們不需要初始參數和類型,也不用立即執行,

完整的簽名如下

export declare function useFetch <T>(
  fn: (args: unknown) => Promise<T>
): [Fetch<T>, (params: unknown) => Promise<T>]

實現如下:

export const useFetchFn = <T>(
  fn: (args: unknown) => Promise<T>
): [Fetch<T>, (params: unknown) => Promise<T>] => {
  
  const data = reactive<Fetch<T>>({
    loading: false, // 默認為false
    value: undefined,
    error: undefined
  }) as Fetch<T>

  const callback = (params: unknown): Promise<T> => 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]
}

驗證如下:

<script setup lang="ts">
import { reactive } from 'vue';
import { useFetchFn } from './hooks/index';

const fn = () => new Promise((resolve) => {
  setTimeout(()=> resolve({data: [], msg: '', code: 200}), 1000)
})

const [data, fetch] = useFetchFn<unknown>(fn)

</script>

<template>
  <h4>公眾號:萌萌噠草頭將軍</h4>

  <!-- 加載中時用css禁用按鈕 -->
  <button
    :style="{'pointer-events': data.loading ? 'none' : 'auto'}"
    @click="fetch({})"
  >{{ data.loading ? 'laoding...' : 'fetch' }}</button>
  
  <h1 v-if="data.loading">loading...</h1>
  <h1 v-else>{{data.value}}</h1>
</template>

fetchfn.giffetchfn.gif

頁面刷新后沒有發出請求,點擊按鈕之后才發出請求!

?? 自動請求函數

我們期望的場景是,

  • 初始化一個請求函數,然后根據初始參數,立即發送請求
  • 當參數發生變化時,自動根據最新參數發送請求
  • 要求返回值包含加載中狀態,錯誤信息以及正常的數據類型。

這個的實現和立即請求函數類似,只需要監聽參數的變化,

完整的簽名如下

export declare function useFetch <T, Params>(
  fn: (args: Params) => Promise<T>,
  initParams: Params  
): Fetch<T>

實現如下:

export const useAutoFetch = <T, Params>(
  fn: (args: Params) => Promise<T>,
  initParams: Params  
): Fetch<T> => {
  
  const data = reactive<Fetch<T>>({
    loading: true,
    value: undefined,
    error: undefined
  }) as Fetch<T>

  const callback = (params: Params): Promise<T> => 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
}

我們驗證下功能

<script setup lang="ts">
import { reactive, watch } from 'vue';
import { useAutoFetch } from './hooks/index';

const fn = () => new Promise((resolve) => {
  setTimeout(()=> resolve({data: [], msg: '', code: 200}), 1000)
})

const params = reactive({
  age: 9
})

const data = useAutoFetch<unknown, object>(fn, params)

watch(params, () => console.log(params))

</script>

<template>
  <h4>公眾號:萌萌噠草頭將軍</h4>
  
  <div>{{ params.age }}</div>
  <!-- 加載中時用css禁用按鈕 -->
  <button
    :style="{'pointer-events': data.loading ? 'none' : 'auto'}"
    @click="() => params.age++"
  >{{ data.loading ? 'laoding...' : 'change params' }}</button>
  
  <h1 v-if="data.loading">loading...</h1>
  <h1 v-else>{{data.value}}</h1>
</template>

auto.gifauto.gif

每次當我們改變參數時自動發送請求。

責任編輯:武曉燕 來源: 萌萌噠草頭將軍
相關推薦

2020-07-22 15:15:28

Vue前端代碼

2025-03-10 08:44:17

2025-06-04 08:35:00

立即執行函數IIFEJavaScript

2025-03-03 12:00:00

JavaScriptfor 循環語言

2024-11-06 10:16:22

2022-09-06 12:20:30

Vue3CVCRUD

2023-03-15 15:54:36

Java代碼

2022-08-28 10:08:53

前端代碼前端

2022-07-06 07:42:14

DOMHook標簽

2024-05-30 11:44:37

2011-08-16 15:06:43

IOS開發異步請求

2022-06-13 08:39:21

Vue3API

2023-09-27 07:49:23

2022-12-19 14:53:07

模型訓練

2024-08-13 09:26:07

2022-07-20 09:06:27

Hook封裝工具庫

2022-06-07 08:59:58

hookuseRequestReact 項目

2024-04-02 08:50:08

Go語言react

2024-07-10 08:39:49

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲欧美在线观看 | 成人福利网 | 欧美日韩国产一区二区三区 | 免费一区二区三区 | 午夜视频在线免费观看 | 亚洲欧美成人在线 | 国产成人精品久久二区二区 | 天天综合成人网 | www国产成人免费观看视频,深夜成人网 | 久久久久久久久精 | 国产精品久久久久久二区 | 国产免费一区二区三区网站免费 | 精品伊人久久 | 成人美女免费网站视频 | av网站免费在线观看 | 国产成人一区二区三区 | 日韩国产三区 | 亚洲人va欧美va人人爽 | 蜜桃在线一区二区三区 | 亚洲一区二区精品视频 | 中文字幕免费中文 | 91电影在线 | 日韩在线精品视频 | 亚洲免费视频一区二区 | 99精品欧美一区二区三区综合在线 | 综合激情网| 国产一极毛片 | 国产精品毛片一区二区在线看 | 亚洲人成人一区二区在线观看 | 中文字幕人成乱码在线观看 | 欧美一级在线观看 | 操操日| 久久国产美女视频 | 国产精品18久久久 | 成人国产午夜在线观看 | 中国黄色毛片视频 | 欧美视频在线播放 | 日韩视频一级 | 中文字幕一区二区三区乱码在线 | 视频一区 国产精品 | 国产乱码久久久久久 |