当前位置:首页 >休闲 >Vue3使用hook封装常见的几种异步请求函数场景,让开发更丝滑 装常种异然后根据初始参数

Vue3使用hook封装常见的几种异步请求函数场景,让开发更丝滑 装常种异然后根据初始参数

2024-06-28 20:00:02 [百科] 来源:避面尹邢网

Vue3使用hook封装常见的使数场几种异步请求函数场景,让开发更丝滑

作者:萌萌哒草头将军 开发 前端 初始化一个请求函数,装常种异然后根据初始参数,见的景让立即发送请求,步请返回请求结果,求函并且返回请求回调函数,更丝方便我们根据新的使数场参数再次调用。

🚀 立即请求函数

我们期望的装常种异场景是,

  • 初始化一个请求函数,见的景让然后根据初始参数,步请立即发送请求
  • 返回请求结果,求函并且返回请求回调函数,更丝方便我们根据新的使数场参数再次调用
  • 要求返回值包含加载中状态,错误信息以及正常的装常种异数据类型。

我的见的景让实现过程如下:

Vue3使用hook封装常见的几种异步请求函数场景,让开发更丝滑 装常种异然后根据初始参数

定义具体的数据返回值签名

Vue3使用hook封装常见的几种异步请求函数场景,让开发更丝滑 装常种异然后根据初始参数

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

完整的签名如下

Vue3使用hook封装常见的几种异步请求函数场景,让开发更丝滑 装常种异然后根据初始参数

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

每次当我们改变参数时自动发送请求。

责任编辑:武晓燕 来源: 萌萌哒草头将军 Vue3参数请求

(责任编辑:百科)

    推荐文章
    热点阅读