3.0 uniApp开发小程序之http拦截器封装

31 阅读1分钟

1 http.ts

import { useMemberStore } from '@/stores'
const baseURL = 'https:xxx'
const httpInterceptor = {
  invoke(options: UniApp.RequestOptions) {
    if (!options.url.startsWith('http')) {
      options.url = baseURL + options.url
    }
    options.timeout = 10 * 1000
    options.header = {
      ...options.header,
      'source-client': 'miniapp',
    }
    const memberStore = useMemberStore()
    const token = memberStore.profile?.token
    token && (options.header.Authorization = token)
  },
}
uni.addInterceptor('request', httpInterceptor)
// 定义返回data的类型,因每个请求result的类型可能不一样,直接在使用的时候传入一个泛型T
interface ResData<T> {
  code: string
  msg: string
  result: T
}
export const $http = <T>(opts: UniApp.RequestOptions) => {
  return new Promise<ResData<T>>((resolve, reject) => {
    uni.request({
      ...opts,
      success(res: UniApp.RequestSuccessCallbackResult) {
        if (res.statusCode === 200) {
          resolve(res.data as ResData<T>)
        } else if (res.statusCode === 401) {
          const memberStore = useMemberStore()
          memberStore.clearProfile()
          uni.navigateTo({ url: 'pages/login/login.vue' })
          reject(res)
        } else {
          uni.showToast({
            icon: 'none',
            title: (res.data as ResData<T>).msg || '请求错误',
          })
          reject(res)
        }
      },
      fail(err) {
        uni.showToast({
          icon: 'none',
          title: '网络错误',
        })
        reject(err)
      },
    })
  })
}

2 API定义 api.ts

 type BannerItem = {
  id: string
  hrefUrl: string
  type: string
  imgUrl: string
}

import { $http } from './http'
//  此处api定义时候传入一个返回的result的类型
export const getBannerData = (params) => {
  return $http<BannerItem[]>({
    method: 'GET',
    url: '',
    data: {
      params,
    },
  })
}

3 index.vue组件调用api获取数据

<script>
import type { BannerItem } from '@/types/home'
const bannerList = ref<BannerItem[]>([])
const getBData = async () => {
  const res = await getBannerData()
  bannerList.value = res.result
}
onLoad(() => {
  getBData()
})
</script>

4 自定义组件Banlist传参

<template>
 <Banlist :bannerList="bannerList"></Banlist>
</template>

5 子组件接收数据

import type { BannerItem } from '@/types/home'
defineProps<{
  bannerList: BannerItem[]
}>()