• Vue3+TS版本Uniapp:封装uni.request请求配置


    作者:前端小王hs

    阿里云社区博客专家/清华大学出版社签约作者✍/CSDN百万访问博主/B站千粉前端up主

    封装请求配置项

    封装拦截器

    uniapp的封装逻辑不同于Vue3项目中直接使用axios.create()方法创建实例(在create方法中写入请求的地址、请求头、超时等内容),代码如下:

    const instance = axios.create({
    	// 后端url地址
    	baseURL: import.meta.env.VITE_API_BASEURL,
    	timeout: 6000, //设置超时
    	headers: {
    		'Content-Type': 'application/x-www-form-urlencoded'
    	}
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    PS:上述代码来自博主在B站的Vue3全家桶+MySQL+Express全栈实战项目源码

    uniapp中,需要使用到一个官方的APIuni.addInterceptor(STRING, OBJECT),这是一个用于拦截作用的API,在规范开发的过程中,会在请求之前为请求的内容拼接url、超时和请求头等信息,这一点在官方文档API的基础拦截器一文中详细的示例,代码如下:

    uni.addInterceptor('request', {
      invoke(args) {
        // request 触发前拼接 url 
        args.url = 'https://www.example.com/'+args.url
      },
      success(args) {
        // 请求成功后,修改code值为1
        args.data.code = 1
      }, 
      fail(err) {
        console.log('interceptor-fail',err)
      }, 
      complete(res) {
        console.log('interceptor-complete',res)
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    所以可以封装一个拦截器的配置项,为所有的uni.request添加请求前置信息,代码如下:

    const baseURL = import.meta.env.VITE_API_BASEURL
    // 添加拦截器
    const httpInterceptor = {
      // 拦截前触发
      invoke(options: UniApp.RequestOptions) {
        // 假设开头为非http的请求url地址
        if (!options.url.startsWith('http')) {
          options.url = baseURL + options.url
        }
        // 请求超时
        options.timeout = 6000
        options.header = {
          ...options.header,
          // 自定义标识符,用于后端区分app、后台或其他渠道请求
          'source-client': 'app',
        }
        // 添加 token 请求头标识
        const token = uni.getStorage('token')
        if (token) {
          options.header.Authorization = token
        }
      },
    }
    
    uni.addInterceptor('request', httpInterceptor)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    这是一段万能的uniapp封装拦截器代码,读者可收藏此文章粘贴即用,下同

    封装uni.request

    这里的封装,参考了axios返回promise对象的实现逻辑,在接口中return一个promise对象,便于在实际环境中更好的获取数据以及进一步处理数据,代码如下:

    type Data<T> = {
    	// 后端返回的通用响应结构
    	statusCode: string
    	msg: string
    	result: T
    }
    // UniApp.RequestOptions为配置网络请求的选项
    // 这里使用了泛型,便于自定义响应结构
    export const http = <T>(options: UniApp.RequestOptions) => {  
      return new Promise<Data<T>>((resolve, reject) => {  
        uni.request({  
          // 拦截器配置内容
          ...options,
          success(res) {
          	// 成功响应
            handleResponse(res, resolve, reject);
          }, 
          fail(err) { 
            handleError(err, reject);
          },  
        });  
      };  
    };  
    
    // resolve和reject不返回任何值,但通知promise更改状态
    const handleResponse = <T>(res: any, resolve: (value: Data<T>) => void, reject: (reason?: any) => void) => {
      // 分离了验证状态码逻辑
      if (isSuccessStatusCode(res.statusCode)) {  
        resolve(res.data as Data<T>);
      // 登录失败
      } else if (res.statusCode === 401) {  
        // 假设 clearUserInfo 是清除用户信息的函数 
        clearUserInfo();
        // 跳转至登录页面
        uni.navigateTo({ url: '/pages/login/index' });
        reject(res);
      } else {
      	// 分离了报错状态码逻辑
        showErrorToast(res.data as Data<T>); 
        reject(res);
      }  
    };  
      
    const handleError = (err: any, reject: (reason?: any) => void) => {
      uni.showToast({
        icon: 'none',  
        title: '网络可能开小差了~',  
      });
      reject(err);
    };
      
    const isSuccessStatusCode = (statusCode: number) => {
      return statusCode >= 200 && statusCode < 300;
    };
      
    const showErrorToast = <T>(data: Data<T>) => {
      uni.showToast({
        icon: 'none',
        title: data.msg || '请求错误',
      });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    关于RequestOptions更多的信息,可以对其ctrl+点击查看内置的接口信息,如下图所示:
    RequestOptions

  • 相关阅读:
    【Linux】安装VMWare虚拟机(安装配置)和配置Windows Server 2012 R2(安装配置连接vm虚拟机)以及环境配置
    结构型模式-装饰器模式
    这些数据泄露方式,80%的企业不易发现
    课设总结【硬件课设】
    【Leetcode】剑指Offer 29:顺时针打印矩阵
    天一个数据分析题(一百七十三)
    TCP socket && UDP && TCP协议 && IP协议 && 以太网等
    Java高级工程师常见面试题(答案)
    若依框架数据源切换为pg库
    【C语言】【结构体的位段】位段的内存分配及注意事项
  • 原文地址:https://blog.csdn.net/weixin_44001222/article/details/138034453