自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Vue3使用hook封裝常見的幾種異步請(qǐng)求函數(shù)場景,讓開發(fā)更絲滑

開發(fā) 前端
初始化一個(gè)請(qǐng)求函數(shù),然后根據(jù)初始參數(shù),立即發(fā)送請(qǐng)求,返回請(qǐng)求結(jié)果,并且返回請(qǐng)求回調(diào)函數(shù),方便我們根據(jù)新的參數(shù)再次調(diào)用。

?? 立即請(qǐng)求函數(shù)

我們期望的場景是,

  • 初始化一個(gè)請(qǐng)求函數(shù),然后根據(jù)初始參數(shù),立即發(fā)送請(qǐng)求
  • 返回請(qǐng)求結(jié)果,并且返回請(qǐng)求回調(diào)函數(shù),方便我們根據(jù)新的參數(shù)再次調(diào)用
  • 要求返回值包含加載中狀態(tài),錯(cuò)誤信息以及正常的數(shù)據(jù)類型。

我的實(shí)現(xiàn)過程如下:

定義具體的數(shù)據(jù)返回值簽名

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>]

函數(shù)實(shí)現(xiàn)如下:

export const useFetch = <T, Params>(
  fn: (args: Params) => Promise<T>,
  initParams: Params  
): [Fetch<T>, (params: Params) => Promise<T>] => {
  
  // 定義基礎(chǔ)的數(shù)據(jù)格式
  const data = reactive<Fetch<T>>({
    loading: true,
    value: undefined,
    error: undefined
  }) as Fetch<T> // 這里會(huì)報(bào)錯(cuò):T類型無法賦值給UnwrapRef<T>類型
  // 我不懂為啥,UnwrapRef是vue的深層響應(yīng)式類型的聲明
  // 這里導(dǎo)致我無法默認(rèn)的類型賦值,不符合直覺,可能是我ts太菜了
  // 懂的大佬評(píng)論區(qū)帶帶我吧
  
  // 定義請(qǐng)求回調(diào)
  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)
  })

  // 立即執(zhí)行
  watchSyncEffect(() => {
    callback(initParams)
  })

  return [data, callback]
}

我們驗(yàn)證下

<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>公眾號(hào):萌萌噠草頭將軍</h4>

  <!-- 加載中時(shí)用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

頁面刷新后立即發(fā)出請(qǐng)求了!

?? 手動(dòng)請(qǐng)求函數(shù)

我們期望的場景是,

  • 初始化一個(gè)請(qǐng)求函數(shù)
  • 返回請(qǐng)求回調(diào)函數(shù),方便我們調(diào)用
  • 要求返回值包含加載中狀態(tài),錯(cuò)誤信息以及正常的數(shù)據(jù)類型

這個(gè)的實(shí)現(xiàn)和上面類似,我們不需要初始參數(shù)和類型,也不用立即執(zhí)行,

完整的簽名如下

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

實(shí)現(xiàn)如下:

export const useFetchFn = <T>(
  fn: (args: unknown) => Promise<T>
): [Fetch<T>, (params: unknown) => Promise<T>] => {
  
  const data = reactive<Fetch<T>>({
    loading: false, // 默認(rèn)為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]
}

驗(yàn)證如下:

<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>公眾號(hào):萌萌噠草頭將軍</h4>

  <!-- 加載中時(shí)用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

頁面刷新后沒有發(fā)出請(qǐng)求,點(diǎn)擊按鈕之后才發(fā)出請(qǐng)求!

?? 自動(dòng)請(qǐng)求函數(shù)

我們期望的場景是,

  • 初始化一個(gè)請(qǐng)求函數(shù),然后根據(jù)初始參數(shù),立即發(fā)送請(qǐng)求
  • 當(dāng)參數(shù)發(fā)生變化時(shí),自動(dòng)根據(jù)最新參數(shù)發(fā)送請(qǐng)求
  • 要求返回值包含加載中狀態(tài),錯(cuò)誤信息以及正常的數(shù)據(jù)類型。

這個(gè)的實(shí)現(xiàn)和立即請(qǐng)求函數(shù)類似,只需要監(jiān)聽參數(shù)的變化,

完整的簽名如下

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

實(shí)現(xiàn)如下:

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)
  })

  // 如果不需要立即執(zhí)行,可沒有這步
  const effects = watchSyncEffect(() => {
    callback(initParams)
  })

  // 自動(dòng)監(jiān)聽參數(shù)變化
  const effects = watch([initParams], () => callback(initParams))
  // 卸載頁面時(shí),關(guān)閉監(jiān)聽
  onUnmounted(() => effects())

  return data
}

我們驗(yàn)證下功能

<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>公眾號(hào):萌萌噠草頭將軍</h4>
  
  <div>{{ params.age }}</div>
  <!-- 加載中時(shí)用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

每次當(dāng)我們改變參數(shù)時(shí)自動(dòng)發(fā)送請(qǐng)求。

責(zé)任編輯:武曉燕 來源: 萌萌噠草頭將軍
相關(guān)推薦

2020-07-22 15:15:28

Vue前端代碼

2025-03-10 08:44:17

2025-03-03 12:00:00

JavaScriptfor 循環(huán)語言

2024-11-06 10:16:22

2022-09-06 12:20:30

Vue3CVCRUD

2022-07-06 07:42:14

DOMHook標(biāo)簽

2011-08-16 15:06:43

IOS開發(fā)異步請(qǐng)求

2022-08-28 10:08:53

前端代碼前端

2023-03-15 15:54:36

Java代碼

2022-06-13 08:39:21

Vue3API

2024-05-30 11:44:37

2024-08-13 09:26:07

2022-07-20 09:06:27

Hook封裝工具庫

2023-09-27 07:49:23

2022-12-19 14:53:07

模型訓(xùn)練

2022-06-07 08:59:58

hookuseRequestReact 項(xiàng)目

2024-04-02 08:50:08

Go語言react

2021-05-18 07:51:37

Suspense組件Vue3

2024-07-10 08:39:49

2021-12-01 08:11:44

Vue3 插件Vue應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)