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

作者:前端小王hs

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

封装请求配置项

封装拦截器

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

ts 复制代码
const instance = axios.create({
	// 后端url地址
	baseURL: import.meta.env.VITE_API_BASEURL,
	timeout: 6000, //设置超时
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded'
	}
});

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

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

ts 复制代码
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)
  }
})

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

ts 复制代码
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)

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

封装uni.request

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

ts 复制代码
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 || '请求错误',
  });
};

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

相关推荐
john_hjy2 分钟前
【无标题】
javascript
奔跑吧邓邓子15 分钟前
npm包管理深度探索:从基础到进阶全面教程!
前端·npm·node.js
软件开发技术深度爱好者24 分钟前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5
前端李易安35 分钟前
ajax的原理,使用场景以及如何实现
前端·ajax·okhttp
汪子熙1 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
Envyᥫᩣ1 小时前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.5 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。7 小时前
案例-表白墙简单实现
前端·javascript·css
数云界7 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd7 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome