小白系列Vite-Vue3-TypeScript:007-配置axios并封装api
创始人
2024-05-24 15:03:59
0

上一篇我们介绍了Vite+Vue3+TypeScript项目中Element Plus的安装和配置,本篇我们来介绍一下如何配置axios并封装api。

axios是一个基于promise的HTTP库,可以用在浏览器和node.js中,其最大的亮点就是支持了ES6里的Promise Api。废话不多说,直接撸起来......

安装axios

有时候可能需要对请求或者相应参数进行解析或者格式转换,所以除了axios库之外,一般我们还会安装qs(一个流行的查询参数序列化和解析库),qs可以将一个普通的object序列化成一个查询字符串,或者反过来将一个查询字符串解析成一个object,而且支持复杂的嵌套。

//安装axios
npm i axios -S//安装qs
npm i qs -S

配置vite环境变量(区分开发和生产环境)

创建环境文件

项目根目录下创建文件 .env.dev(开发测试环境)和文件 .env.prod(生产环境)

.env.dev文件代码如下

#(.env.dev 测试/开发环境变量配置)
VITE_ENV = development# base api# 初始地址, 注意端口号要与vite.config.ts的server部分一致
VITE_SOURCE_URL = http://localhost:8088# 基础域名
VITE_BASE_API = http://localhost:8088# 服务地址
VITE_SERVE_ADD = /api

.env.prod文件代码如下

#(.env.prod 生产环境变量配置)
VITE_ENV = development# base api# 初始地址, 注意端口号要与vite.config.ts的server部分一致
VITE_SOURCE_URL = http://192.168.5.106:8088# 基础域名
VITE_BASE_API = http://192.168.5.106:8088# 服务地址
VITE_SERVE_ADD = /api

更新指令

修改package.js的脚本命令内容

"scripts": {"dev": "vite --mode dev","prod": "vite --mode prod","build": "vue-tsc && vite build --mode prod","preview": "vite preview"
},

这样配置完成后,运行npm run dev或npm run prod或build时会把自定义的环境变量载入进去,避免了每次打包和开发都要临时修改变量的尴尬。

创建config.ts配置文件

上面我们已经创建好了环境变量,在src目录下新建config.ts文件来接收环境变量以及后面可能出现的公用配置。

/** 环境变量 */
const ENV = import.meta.env;  // vite是以这种方式获取环境变量/** 基础域名 */
export const SOURCE_URL = ENV.VITE_SOURCE_URL;
export const BASE_URL = ENV.VITE_BASE_API;/** 基础服务地址 */
export const URL = BASE_URL + '/api';/** 超时时间 */
export const TIMEOUT = 6000;

这样在后面创建axios实例和封装api的时候,就可以直接通过config.ts文件来读取配置了。

创建axios实例文件

在项目src/utils目录下(没有的话创建即可)新建request.ts文件,这个文件就是我们要书写axios的api封装。封装过程中用到了Message组件,刚好上一篇我们已经介绍了安装及配置ElementPlus的过程。同时引入token管理。

导入所需依赖

import axios, { AxiosRequestConfig } from 'axios'
import qs from 'qs'
import { setLocalStorage, getLocalStorage } from './localstorage'
import { BASE_URL, TIMEOUT, SOURCE_URL } from "@/config";

导入qs的时候一般情况下,编辑器会报错“无法找到模块“qs”的声明文件”

因为TypeScript中s不能直接这样引入js类型库,解决方法:在src目录下新建一个globe.d.ts,添加如下代码即可

declare module "qs"

创建实例

const instance = axios.create({baseURL: BASE_URL,timeout: TIMEOUT,headers: {'Accept': 'application/json','Content-Type': 'application/json'}
})

配置请求拦截器

// http request 请求拦截器
instance.interceptors.request.use(config => {config.headers.AcceptLanguage = getLocalStorage("locale");if (localStorage.myToken) {config.headers.Authorization = getLocalStorage("myToken");}return config},err => {return Promise.reject(err)}
)

配置响应拦截器

// http response 响应拦截器
instance.interceptors.response.use(response => {return handleData(response.data)},error => {const errData = error.response.dataif (errData.status === 500) {setLocalStorage('myToken');window.location.href = sourceUrl;}let err = errData.message;if (err != '' && err != null && err != undefined) {ElMessage({type: 'error',message: errData.message})return Promise.reject(errData)} else {ElMessage({type: 'error',message: 'HTTP:服务器遇到错误,请求失败。'})}}
)

封装API

// API封装
const get = async (url: string) => {/**......可以在这里自定义封装处理方法......*/try {return await instance.get(url)} catch (error) {return handleError(error)}
}

完整代码

request.ts

import axios, { AxiosRequestConfig } from 'axios'
import qs from 'qs'
import { setLocalStorage, getLocalStorage } from './localstorage'
import { BASE_URL, TIMEOUT, SOURCE_URL } from "@/config";
const instance = axios.create({baseURL: BASE_URL,timeout: TIMEOUT,headers: {'Accept': 'application/json','Content-Type': 'application/json'}
})
// http request 请求拦截器
instance.interceptors.request.use(config => {config.headers.AcceptLanguage = getLocalStorage("locale");if (localStorage.myToken) {config.headers.Authorization = getLocalStorage("myToken");}return config},err => {return Promise.reject(err)}
)
// http response 响应拦截器
instance.interceptors.response.use(response => {return handleData(response.data)},error => {const errData = error.response.dataif (errData.status === 500) {setLocalStorage('myToken');window.location.href = SOURCE_URL;}let err = errData.message;if (err != '' && err != null && err != undefined) {ElMessage({type: 'error',message: errData.message})return Promise.reject(errData)} else {ElMessage({type: 'error',message: 'HTTP:服务器遇到错误,请求失败。'})}}
)// API封装
const get = async (url: string) => {/**......可以在这里自定义封装处理方法......*/try {return await instance.get(url)} catch (error) {return handleError(error)}
}
const post = async (url: string, data?: any, config?: AxiosRequestConfig | undefined) => {/**......可以在这里自定义封装处理方法......*/try {return await instance.post(url, data, config)} catch (error) {return handleError(error)}
}
const deleteFn = async (url: string, config?: AxiosRequestConfig | undefined) => {/**......可以在这里自定义封装处理方法......*/try {return await instance.delete(url, config)} catch (error) {return handleError(error)}
}
const postJSON = async (url: string, data?: any, config?: AxiosRequestConfig | undefined) => {/**......可以在这里自定义封装处理方法......*/data = qs.stringify(data);try {return await instance.post(url, data, config)} catch (error) {return handleError(error)}
}
const patchFn = async (url: string, data?: any, config?: AxiosRequestConfig | undefined) => {/**......可以在这里自定义封装处理方法......*/try {return await instance.patch(url, data, config)} catch (error) {return handleError(error)}
}
// 对请求返回的错误进行自处理
function handleError(error: any) {return error
}
// 对响应的数据进行自处理
function handleData(data: any) {return data
}
export default {get: get,post: post,postJSON: postJSON,delete: deleteFn,patch: patchFn
}

localstorage.ts


export const setLocalStorage = (key: string, value?: string, hours?: number) => {value = JSON.stringify(value);// 设置过期原则if (!value) {localStorage.removeItem(key)} else {let Hours = hours || 24; // 以小时为单位,默认24小时let exp = new Date();localStorage[key] = JSON.stringify({value,expires: exp.getTime() + Hours * 1000 * 60 * 60,//失效时间})}
}
export const getLocalStorage = (key: string) => {try {let ls = JSON.parse(localStorage[key]);if (!ls || ls.expires < Date.now()) {return ''} else {return JSON.parse(ls.value)}} catch (e) {// 兼容其他localstoragereturn localStorage[key]}
}

config.ts

/** 环境变量 */
const ENV = import.meta.env;  // vite是以这种方式获取环境变量/** 基础域名 */
export const SOURCE_URL = ENV.VITE_SOURCE_URL;
export const BASE_URL = ENV.VITE_BASE_API;/** 基础服务地址 */
export const URL = BASE_URL + '/api';/** 超时时间 */
export const TIMEOUT = 6000;

OK,这样基本就完成了axios的安装和api封装了!

我相信,每天学习一点点,收获成长亿点点!

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...