【unibest】第8篇 —— 请求篇

大家好,我是 菲鸽,今天带给大家 unibest 文档系列文章第8篇 —— 请求篇。欢迎食用~

本篇分为三块内容:

  • 普通请求

  • 图片上传

  • 多后台地址

普通请求

普通请求分2种处理,一种是只在页面请求一次的一次性请求,这种请求占大多数;一种是项目多处用到的请求,这种请求占小部分,需要单独编写一个请求函数放到 api文件夹 or service文件夹

unibest 里面是使用 service文件夹 后面不再说明。

下面来分别演示:

一次性请求

template 部分编码如下:

<template>
  <button @click="run">请求</button>
  <view v-if="loading" class="text-blue h-10">请求中...</view>
  <view v-if="error" class="text-red h-10">请求错误</view>
  <view v-else class="text-green h-10">{{ JSON.stringify(data) }}</view>
</template>

script 部分使用 菲鸽 封装好的 useRequest 即可实现请求状态一体化,如下:

<script setup>
type IFooItem = { name: string }
const { loading, error, data, run } = useRequest<IFooItem>(() => httpGet('/foo', { name: '菲鸽' }))
</script>

看吧,使用非常简单。

重复性请求

重复性请求一次性请求html部分 是一样的,唯一的区别是 请求函数 放到了 service文件夹,如下所示:

<script setup>
import { getFooAPI, IFooItem } from '@/service/index/foo' // 看这里
const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI('菲鸽'))
</script>

对应的 src/service/index/foo.ts 文件如下:

import { http, httpGet } from '@/utils/http'
export interface IFooItem {
  id: string
  name: string
}

/** GET 请求 */
export const getFooAPI = (name: string) => {
  return http<IFooItem>({
    url: `/foo`,
    method: 'GET',
    query: { name },
  })
}

/** GET 请求 - 再次简化,看大家是否喜欢这种简化 */
export const getFooAPI2 = (name: string) => {
  return httpGet<IFooItem>('/foo', { name })
}

依然非常简洁,深受妹子喜爱。

图片上传

template 部分编码如下:

<template>
  <view class="p-4 text-center">
    <wd-button @click="run">选择图片并上传</wd-button>
    <view v-if="loading" class="text-blue h-10">上传...</view>
    <template v-else>
      <view class="m-2">上传后返回的图片地址:</view>
      <view class="m-2">{{ data }}</view>
      <view class="h-80 w-full">
        <image v-if="data" :src="data" mode="scaleToFill" />
      </view>
    </template>
  </view>
</template>

script 部分使用 菲鸽 封装好的 useUpload 即可实现请求状态一体化,如下:

<script lang="ts" setup>
const { loading, data, run } = useUpload<string>({ user: '菲鸽' })
</script>

使用非常简单,深受汉子和妹子的喜爱。

多后台地址

上面的 普通请求 默认是只有一个请求地址的,在 .env 里面配置 VITE_SERVER_BASEURL,如下:

VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'

并且在 src/interceptors/request.ts 里面有设置:

  • 如果是 http 开头的请求路径,则直接请求

  • 如果不是,则拼接上 VITE_SERVER_BASEURL

但在多后台地址时就不能这么玩了,需要处理如下:(关注上图的箭头部分)

// 可以写一个映射对象,如:
const proxyMap = {
  cms:'http://localhost:8080/cms',
  ums:'http://localhost:8080/ums',
}

// 拦截器部分(上图箭头部分)修改如下
Object.keys(proxyMap).forEach(key=>{
  if(options.url.startsWith(`/${key}`)){
    options.url = proxyMap[key] + options.url
  }
}

// 接口调用的地方使用如下格式:
export const getFooAPI = (name: string) => {
  return http<IFooItem>({
    url: `/cms/foo`, // 看这里,前缀不用!!!
    method: 'GET',
    query: { name },
  })
}

useRequest + useUpload 源码

授人予鱼不如授人以渔,下面看看2个文件的源码吧。

useRequest

文件 src/hooks/useRequest.ts 源码如下:

type IUseRequestOptions<T> = {
  /** 是否立即执行,如果是则在onLoad执行 */
  immediate?: boolean
  /** 初始化数据 */
  initialData?: T
}

/**
 * useRequest是一个定制化的请求钩子,用于处理异步请求和响应。
 * @param func 一个执行异步请求的函数,返回一个包含响应数据的Promise。
 * @param options 包含请求选项的对象 {immediate, initialData}。
 * @param options.immediate 是否立即执行请求,默认为true。
 * @param options.initialData 初始化数据,默认为undefined。
 * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
 */
export default function useRequest<T>(
  func: () => Promise<IResData<T>>,
  options: IUseRequestOptions<T> = { immediate: true },
) {
  const loading = ref(false)
  const error = ref(false)
  const data = ref<T>()
  const run = async () => {
    loading.value = true
    func()
      .then((res) => {
        data.value = res.data
        error.value = false
      })
      .catch((err) => {
        error.value = err
      })
      .finally(() => {
        loading.value = false
      })
  }

  onLoad(() => {
    options.immediate && run()
  })
  return { loading, error, data, run }
}

注意,需要在 .env 里面配置 VITE_SERVER_BASEURL,用在 src/interceptors/request.ts 文件拼接请求地址;而 多后台地址 时则用不上,可以删除。

VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'

useUpload

文件 src/hooks/useUpload.ts 源码如下:

/**
 * useUpload 是一个定制化的请求钩子,用于处理上传图片。
 * @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
 * @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
 */
export default function useUpload<T>(formData: Record<string, any> = {}) {
  const loading = ref(false)
  const error = ref(false)
  const data = ref<T>()
  const url = import.meta.env.VITE_UPLOAD_BASEURL
  const run = () => {
    // #ifdef MP-WEIXIN
    // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
    // 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
    uni.chooseMedia({
      count: 1,
      mediaType: ['image'],
      success: (res) => {
        console.log(res)
        loading.value = true
        const tempFilePath = res.tempFiles[0].tempFilePath
        uni.uploadFile({
          url,
          filePath: tempFilePath,
          name: 'file',
          formData,
          success: (uploadFileRes) => {
            console.log(uploadFileRes.data)
            data.value = uploadFileRes.data as T
          },
          fail: (err) => {
            console.log('uni.uploadFile err->', err)
            error.value = true
          },
          complete: () => {
            loading.value = false
          },
        })
      },
      fail: (err) => {
        console.log('uni.chooseMedia err->', err)
        error.value = true
      },
    })
    // #endif
    // #ifndef MP-WEIXIN
    uni.chooseImage({
      count: 1,
      success: (res) => {
        console.log(res)
        loading.value = true
        const tempFilePath = res.tempFilePaths[0]
        uni.uploadFile({
          url,
          filePath: tempFilePath,
          name: 'file',
          formData,
          success: (uploadFileRes) => {
            console.log(uploadFileRes.data)
            data.value = uploadFileRes.data as T
          },
          fail: (err) => {
            console.log('uni.uploadFile err->', err)
            error.value = true
          },
          complete: () => {
            loading.value = false
          },
        })
      },
      fail: (err) => {
        console.log('uni.chooseImage err->', err)
        error.value = true
      },
    })
    // #endif
  }

  return { loading, error, data, run }
}

注意,需要在 .env 里面配置 VITE_UPLOAD_BASEURL:

VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload'

总结

本文介绍了多种请求方式,使用都非常简单,最后给出了 useRequestuseUpload 的源码。

希望您收获的不仅是 ,还有

unibest 链接地址

下面的是就的账号和文档,只是留个纪念。

微信交流群 因不能贴引流二维码,有需要的同学请看 官方文档微信群

全文完~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值