微信小程序111~120

发布于:2025-07-13 ⋅ 阅读:(18) ⋅ 点赞:(0)
1.完善请求-响应拦截器

如何判断成功还是失败?

  1. 如果成功,传递成功数据的同时新增 isSuccess:true字段
  2. 如果失败,传递失败数据的同时新增 isSuccess:false字段
1.使用请求

在这里插入图片描述

//配置请求拦截器
instance.interceptors.request = (config) => {
  const token = getStorage('token')
  if (token) {
    config.header['token'] = token
  }
  return config
}
//配置响应拦截器
instance.interceptors.response = async (response) => {
  return response
}

switch ((data, code)) {
  case 200:
    return data
  case 208:
    const res = await modal({
      content: '失败,请重新登录',
      showCancal: false
    })
    if (res) {
      clearStorage()
      wx.navigateTo({
        url: '/pages/login/login'
      })
    }
    return Promise.reject(response)
  default:
    toast({
      title: '程序出现异常,请联系客服或稍后重试'
    })
    return Promise.reject(response)
}
export default instance
2.请求封装-添加并发请求
  1. 使用 async 和await方式,当第一个请求结束以后才能发起第二个请求,会造成请求的阻塞,从而影响页面的渲染速度。
  async allHandler () {
       await instance.get('/index/findBanner')
       await instance.get('/index/findBannerCategory1')
       await instance.get('/index/findBanner')
       await instance.get('/index/findBannerCategory1')
  }
  1. 使用 Promise.all() 方式,能将多个请求同时发送,不会造成堵塞,不影响速度。
  async allHandler () {
		await Promise.all([instance.get('/index/findBanner'), instance.get('/index/findBannerCategory1'), instance.get('/index/findBanner'), instance.get('/index/findBannerCategory1')])
		  }

封装一下:

  all(...promise) {
    return Promise.all(promise)
  }
2.添加loading
  1. 在请求发送之前,需要通过wx.showLoading展示loading效果
  2. 服务器响应数据以后,需要调用wx.hideLoading隐藏loading效果
complete: () => {
    wx.hideLoading()
}

三个问题:
(1)每次请求都会执行 wx.showLoading(),但是页面中只会显示一个,后面的 loading 会将前面的覆盖。
(2)同时发起多次请求,只要有一个请求成功响应就会调用 wx.hideLoading,导致其他请求还没完成,也不会 loading。
(3)请求过快 或一个请求在另一个请求后立即触发,这时候会出现 loading 闪烁问题。

我解决这三个问题:首先在类中新增一个实例属性 queue,初始值是一个空数组

(1)发起请求之前,判断 queue 如果是空数组则显示 loading ,然后立即向 queue 新增请求标识。
(2)在 complete 中每次请求成功结束,从 queue 中移除一个请求标识,queue 为空时隐藏 loading。
(3)为了解决网络请求过快产生 loading 闪烁问题,可以使用定时器来做判断即可。

3.控制loading显示

需要一个开关来控制 loading 显示。

  1. 类内部设置默认请求参数 isLoading 属性,默认值是 true,在类内部根据 isLoading 属性做判断即可
  2. 某个接口不需要显示 loading 效果,可以在发送请求的时候,可以新增请求配置 isLoading 设置为 false
  3. 整个项目都不需要显示 loading 效果,可以在实例化的时候,传入 isLoading 配置为 false
  defaults = {
    baseURL: '', // 请求基准地址
    url: '', // 接口的请求路径
    data: null, // 请求参数
    methods: 'GET', // 默认的请求方法
    // 请求头
    header: {
      'Content-type': 'application/json' // 设置数据的交互格式
    },
    timeout: 60000, // 默认的超时时长,默认为一分钟
    isLoading: true
  }


if(options.loading) {
}
4.封装uploadAPI

将本地资源上传到服务器

wx.uploadFile({
    // 开发者服务器地址、接口地址
    url: '',
    // 要上传的文件路径
    filePath: avatarUrl,
    // 文件对应的key,服务器需要根据key来获取文件的二进制信息
    name: 'file',
    success: (res) => {
        // 服务器返回的数据是JSON字符串,要用JSON.parse转换
        res.data = JSON.parse(res.data)
        this.setData({
            avatarUrl: res.data.data
        })
    }
})

对其进行封装
(1)首先在WxRequest类内部创建upload实例方法,实例方法接收四个属性

return new Promise((resolve, reject) => {
      if (op.methods === 'UPLOAD') {
        wx.uploadFile({
          ...options,
          success: (res) => {
            res.data = JSON.parse(res.data)
            // 合并参数
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            })
            resolve(this.interceptors.response(mergeRes))
          },
          fail: (err) => {
            const mergeRes = Object.assign({}, err, {
              config: options,
              isSuccess: false
            })
            reject(this.interceptors.response(mergeRes))
          }
        })
      } else {
        wx.request({
          ...options,
          success: (res) => {
            resolve(res)
          },
          fail: (err) => {
            reject(err)
          }
        })
      }
    })
5.使用npm包发送请求
import WxRequest from 'mina-request'
import { getStorage, clearStorage } from './storage'
import { toast, modal } from './extendApi'
// 对 WxRequest 进行实例化
const instance = new WxRequest({
  baseURL: 'https://gmall-prod.atguigu.cn/mall-api', // 使用时请换成真实接口
  timeout: 1000, // 超时时长
  isLoading: false // 是否使用默认的 loading 效果
})

// 添加请求拦截器
instance.interceptors.request = (config) => {
  const token = getStorage('token')
  if (token) {
    config.header['token'] = token
  }
  // 在发送请求之前做些什么
  return config
}

// 添加响应拦截器
instance.interceptors.response = async (response) => {
  const { isSuccess, data } = response
  if (!isSuccess) {
    toast({
      title: '网络异常请重启',
      icon: 'error'
    })
    return Promise.reject(response)
  }
  switch ((data, code)) {
    case 200:
      return data
    case 208:
      const res = await modal({
        content: '鉴权失败,请重新登录',
        showCancal: false
      })
      if (res) {
        clearStorage()
        wx.navigateTo({
          url: '/pages/login/login'
        })
      }
      return Promise.reject(response)
    default:
      toast({
        title: '程序出现异常,请联系客服或稍后重试'
      })
      return Promise.reject(response)
  }
  //   return response
}
// 导出实例
export default instance

6.小程序设置环境变量

开发环境需要调用开发板的接口地址,生产环境需要调用正式版的接口地址,小程序提供了wx.getAccountInfoSync()接口,获取当前账号信息。
开发版====>develop
体验版====>trial
正式版====>release

// 用来配置当前小程序项目的环境变量
const { miniProgram } = wx.getAccountInfoSync()
const { miniProgram } = miniProgram
let env = {
  baseURL: 'https://gmall-prod.atguigu.cn/mall-api'
}
switch (envVersion) {
  case develop:
    env.baseURL = 'https://gmall-prod.atguigu.cn/mall-api'
    break
  case trial:
    env.baseURL = 'https://gmall-prod.atguigu.cn/mall-api'
    break
  case release:
    env.baseURL = 'https://gmall-prod.atguigu.cn/mall-api'
    break

  default:
    env.baseURL = 'https://gmall-prod.atguigu.cn/mall-api'
    break
}
export { env }

7.接口调用方式说明

一个接口是一个方法,每个方法需要单独导出

// 导入封装的网络请求模块实例
import http from '../utils/http'
// 获取首页轮播图数据
export const reqSwiperData = () => http.get('/index/findBanner')

网站公告

今日签到

点亮在社区的每一天
去签到