代码地址,request分支:https://gitee.com/lsjWeiYi/vue3-frame/tree/request/
web到此还缺一个http请求功能,然后就可以实现功能了。
当前http请求基本都使用axios,然后我发现官方还为框架提供了封装,vue-axios,但是网上资料很少,估计是大部人都是在网上借鉴别人实现得工具类。我也一样。
但是我还是尝试使用框架的工具类,我测试功能是正常的,下面介绍下整个流程。
- 在package.json添加依赖:
"axios": "^0.26.0",
"vue-axios": "^3.4.1",
-
实现http请求的工具类:
首先type.ts:
// 接收response的对象类
export interface IResponseData<T> {
status: number;
message?: string;
data: T;
code: string;
}
然后axios配置类index.ts:
import axios from "axios";
import { AxiosRequestConfig, AxiosResponse } from "axios";
// axios配置在此实现
export const axiosConfig = function () {
axios.defaults.baseURL = "http://localhost:10001/"; // 设置服务端地址
axios.defaults.timeout = 3000; // 设置超时时间
axios.interceptors.request.use( // 请求中间件
(config: AxiosRequestConfig) => {
/**
* 实现自己的业务逻辑
* 1.开启全屏加载动画之类
* 2.数据加密config。data
* 3.给请求头添加信息等(token 结合sessionStorage,localStorage,vuex这些)
*
*/
return config;
},
(error) => {
/* 请求错误的业务逻辑
1. 关闭全屏loading动画
2. 重定向到错误页
*/
return Promise.reject(error); // 为了可以在代码中catch到错误信息
}
); //end request.use
axios.interceptors.response.use( // 响应中间件
(response: AxiosResponse) => {
/*
1. 关闭全屏loading动画
2. 数据解密
3. 根据 response.data.code 做不同的错误处理
4. ……
*/
return response;
},
(error) => {
return Promise.reject(error);
}
); //end response.use
};
再之后是工具类具体实现request.ts:
import axios from "axios";
import { IResponseData } from "./type";
// 实现gey方法
// 这里采用泛型T实现,能够达到数据直接解析成对应的对象
export function get<T>(url: string, params?: any): Promise<IResponseData<T>> {
return axios.get(url, params);
}
// 实现post方法
export function post<T>(url: string, params: any): Promise<IResponseData<T>> {
return axios.post(url, params);
}
// 其他方法可自己拓展
- 最后还需要在main.ts注册启用:
import axios from 'axios'
import VueAxios from 'vue-axios'
import { axiosConfig } from './utils/http'
......此处省略无关代码
axiosConfig() // 加载axios配置
app.use(VueAxios, axios).mount('#app') // 此处省略其他插件
到此就可以使用了,这种实现方式我认为有两个特点:
- 泛型可以将数据直接解析成对应的数据结构体
- 全局唯一axios变量,在其他文件import axios使用的都是同一个对象
使用测试
为了简单,我直接在App.vue进行测试,这里的前提是我在后台实现了一个get接口http://localhost:10001/v2/health,它的返回值是{“version”:“v2”}。
然后看代码:
首先实现了一个api接口“health.ts”,这里很简单,其实就是在封装一些请求的路径:
import { get } from '@/utils/http/request'
export function getHealth<T>() {
return get<T>('v2/health')
}
然后是调用的代码App.vue:
<script setup lang="ts">
import { useStore } from "./store/index";
import { getHealth } from "~/service/api/health";
const myStore = useStore();
// 定义response的数据结构体
interface health {
version: string;
}
// 按钮的点击回调函数
function get() {
getHealth<health>().then((res) => {
// 修改全局变量name,这里内容是上一节继承下来的
myStore.$patch({
name: res.data.version,
});
});
}
</script>
然后我们看页面:
然后点击按钮后:
内容就变成response的返回内容了。整个流程就这样实现了。