文章目录
- 一、概要
- 二、用法展示
- 封装后端api
- .vue文件中进行网络请求
- 三、技术细节
- 我们一共要封装出两个文件http.ts与commonHttp.ts(这两个文件可以自己命名),其中http.ts用在第一次封装axios,其细节在于对网络请求进行拦截器的配置与一些安全设置相关的内容。commonHttp.ts用于规范我们的请求格式,包括对请求接口的确定,请求成功回调,失败回调等...
- http.js
- commonHttp.js
- 小结
一、概要
文章介绍了如何使用TypeScript来二次封装Axios,以规范项目前端开发流程中不同成员在网络请求以及一些对于请求安全的配置,同时也便于后期审阅与修改
二、用法展示
封装后端api
- 第一步引入封装好的req文件
- 根据实际接口进行模板封装,模板如下
// params将会自动识别为get方法的参数,data则是其余类似POST方法的参数
export let 接口名称 = (params:object,data:obejct) => {
return req.request({
method:'方法类型',
url:'接口地址',
data? post等方法参数
params? put方法参数
headers? 请求头配置(如Content-type)
})
}
- 在vue文件中根据js文件导出的名称引用即可
.vue文件中进行网络请求
让我们只关注重要的逻辑代码
- 因为Vue3中我们不能在setup函数中调用this,因此我们可以借助Vue官方给予的一个接口getCurrentInstance()来获取当前页面代理
const { proxy }: any = getCurrentInstance()
- 拥有了proxy后我们就可以正式进行网络请求了,首先让我们明确调用接口所需的参数(如下图中的data),然后只需填充下面这个模板就能够成功进行网络请求了!
proxy.$cHttp({
func:请求方法【就是我们封装好的后端接口】[必填],
data/params:接口所需的参数[可选]
success:成功回调[可选] ,
....
})
只用简单的两步,我们就成功的发送了我们的网络请求!但其实这次封装的功能远不止这么简单!!
三、技术细节
我们一共要封装出两个文件http.ts与commonHttp.ts(这两个文件可以自己命名),其中http.ts用在第一次封装axios,其细节在于对网络请求进行拦截器的配置与一些安全设置相关的内容。commonHttp.ts用于规范我们的请求格式,包括对请求接口的确定,请求成功回调,失败回调等…
不难发现commonHttp其实是我们上述实例中$cHttp的全程,当然这两个名字你也可以diy!
http.js
- 我们构造一个Request类,该类的本质其实就是axios,我们只是通过这个类初始化一些对axios的配置
- 我们可以通过构造函数来定制一些项目中的请求约束,例如携带token进行请求等
import config from '../config'
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import VueCookies from 'vue-cookies'
const Cookies: any = VueCookies
class Request {
instance: AxiosInstance
baseConfig: AxiosRequestConfig = {
baseURL: config.API_BASE_URL,
timeout: 10000,
withCredentials: true
}
//构造方法,参数为config,最终返回的实例config将为参数config与baseConfig的组合值
constructor(config: AxiosRequestConfig) {
this.instance = axios.create(Object.assign(this.baseConfig, config))
//请求拦截器
this.instance.interceptors.request.use(
(config) => {
//从cookies或者pinia中获取token,用于后端验证
const satoken = Cookies.get('satoken')
if (satoken) {
// config.headers['cookie'] = `satoken=${satoken}`
}
return config;
},
(error: any) => {
return Promise.reject(error)
})
//响应拦截器
this.instance.interceptors.response.use(
(res: AxiosResponse) => {
return res;
},
(error: any) => {
return Promise.reject(error.response)
}
)
}
//请求方法
public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
return this.instance.request(config)
}
}
export default new Request({})
commonHttp.js
- 该文件往全局环境中插入一个‘插件’ ,在这里我们命名它为 $cHttp。这样一来我们就可以在任意位置使用这个 $cHttp 进行网络请求了
- 类似下图,我们可以根据我们定义的cHttp(详见interface),在调用时进行一些个性化的配置,这些配置在文件中有详细的注释,并且贴心的是即使你懒得配置也没关系(func是一定要的!!!),大部分参数我们都有默认值
import { AxiosResponse } from "axios"
import { App } from "vue"
interface cHttp {
func?: any//调用方法
params?: object//请求url参数
data?: object//请求体参数
success?: Function//成功回调
final?: Function//最终执行回调
successMsg?: boolean//请求成功是否弹出提示框
fail?: Function//返回后端错误码回调
error?: Function//返回http协议错误码回调
}
export default {
install: (app: App) => {
app.config.globalProperties.$cHttp = (obj: cHttp) => {
let func = obj.func
let params = obj.params
let data = obj.data
let success = obj.success
let final = obj.final
let successMsg = obj.successMsg
let fail = obj.fail
let error = obj.error
if (successMsg === null || successMsg === undefined) {
successMsg = true
}
funCall(func, params, data)
.then((res: AxiosResponse) => {
//调用接口成功处理
if (res.data.code == 200) {
if (successMsg) {
successMsgFunction(res)
}
if (!success) {
defaultSuccess(res);
} else {
success(res);
}
return true;
}
//调用接口失败处理
else {
if (!fail) {
defaultFail(res)
} else {
fail(res)
}
return false;
}
})//调用接口错误处理
.catch((err: Error) => {
if (!error) {
defaultError(err)
} else {
error(err);
}
return false;
})//最终执行
.finally((_: any) => {
if (final) {
final()
}
})
}
}
}
//调用func方法
function funCall(func: Function, params: object | undefined, data: object | undefined) {
return func(params, data)
}
//成功消息提示
function successMsgFunction(res: AxiosResponse) {
if (res.data.msg) {
ElMessage.success(res.data.msg)
}
}
//默认成功回调
function defaultSuccess(res: AxiosResponse) {
}
//默认请求后返回后端错误码处理回调函数
function defaultFail(res: AxiosResponse) {
console.log('defaultFail', res)
if (res.data.msg || res.data.error) {
ElMessage.error(`出错了! ${res.data.msg ? res.data.msg : ""}${res.data.error ? res.data.error : ""}。`)
}
}
//默认请求后返回http协议错误码回调函数
function defaultError(error: Error) {
console.error(error)
ElMessage.error('请求失败!')
}
小结
一个简单且灵活的网络请求插件就这样搞定了!