【前端】Axios+TS二次封装与Vue3+Pinia结合使用
本测试项目为 Vite + Vue3 + Ts + Axios + Pinia
创建项目:
npm init vite@latest vite-vue3-ts
安装依赖:
pnpm i axios pinia
在main.ts中注册pinia
import { createApp } from 'vue'
import {createPinia} from 'pinia'
const pinia = createPinia()
import App from './App.vue'
createApp(App).use(pinia).mount('#app')
1、在/src/utils/request.ts中
axios二次封装
import axios, {
AxiosInstance,
AxiosError,
InternalAxiosRequestConfig,
AxiosResponse,
} from "axios";
//接口地址
const baseURL = "http://127.0.0.1:3001"
//创建axios实例
const service: AxiosInstance = axios.create({
baseURL,
//超时时间
timeout: 5000
})
//添加请求拦截器
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
//在发送请求之前做些什么
const token = localStorage.getItem("token")
if (token) {
config.headers.Authorization = token
}
return config
},
(error: AxiosError) => {
//对请求错误做些什么
console.log(error, "请求错误:request-error");
return Promise.reject(error)
}
)
//添加响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
//对响应数据做点什么
return response.data;
},
(error: AxiosError) => {
//对响应错误做点什么
console.log(error, "响应错误:response-error");
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '请求错误';
break;
case 401:
error.message = '未授权,请登录';
break;
case 403:
error.message = '拒绝访问';
break;
case 404:
error.message = `请求地址出错: ${error.response.config.url}`;
break;
case 408:
error.message = '请求超时';
break;
case 500:
error.message = '服务器内部错误';
break;
case 501:
error.message = '服务未实现';
break;
case 502:
error.message = '网关错误';
break;
case 503:
error.message = '服务不可用';
break;
case 504:
error.message = '网关超时';
break;
}
let errorInfo = {
code: error.response.status,
message: error.message
};
console.log("errorInfo:", errorInfo);
}else{
let errorInfo = {
message: error.message
};
console.log("errorInfo:", errorInfo);
}
//可以对错误信息进行集中操作,统一管理
return Promise.reject(error);
}
)
export default service;
2、在/src/api/user.ts中
import service from "../utils/request";
interface IUser {
id: number;
name: string;
age: number;
}
// 获取用户信息
export const getUserById = (id: number): Promise<IUser> => {
return service({
url: `/users/${id}`,
method: "get",
});
};
// 获取用户列表
export const getUserList = (params: { _page: number, _limit: number }): Promise<IUser[]> => {
return service.get("/users", { params });
};
3、在/src/api/index.ts中
统一管理
//用户模块
export { getUserById, getUserList } from "./user.ts";
4、在/src/pinia/user.ts中
import { defineStore } from 'pinia'
import { getUserById, getUserList } from '../api/index.ts'
import { IUserStore } from './types.ts'
const useUserStore = defineStore({
id: 'user',
state: (): IUserStore => ({
user: {},
userList: [],
}),
actions: {
async getUserByIdAction(payload: number) {
const result = await getUserById(payload)
this.user = result
},
async getUserListAction(payload:{ _page: number, _limit: number }) {
const result = await getUserList(payload)
this.userList = result
}
},
})
export default useUserStore
5、在/src/pinia/types.ts中
export interface IUser {
id?: number;
name?: string;
age?: number;
}
export type IUserList = IUser[];
export interface IUserStore {
user: IUser;
userList: IUserList;
}
6、在App.vue组件中使用
<template>
<div>
{{ user.id }}--{{ user.name }}--{{ user.age }}
</div>
<ul>
<li v-for="i in userList" :key="i.id">
{{ i.id }}-{{ i.name }}-{{ i.age }}
</li>
</ul>
</template>
<script setup lang="ts">
import useUserStore from './pinia/user.ts'
import { storeToRefs } from 'pinia'
//转为响应式
const { user, userList } = storeToRefs(useUserStore())
const { getUserByIdAction, getUserListAction } = useUserStore()
//获取id唯一的用户
getUserByIdAction(1)
//获取用户列表
getUserListAction({_page: 1, _limit: 10})
</script>