封装axios
import { useUserStore } from '@/stores' // 引入pinia里的数据
import axios, { type Method } from 'axios' // 引入axios和axios自带的泛型
// 1. 新 axios 实例,基础配置
const baseURL = '基地址'
const instance = axios.create({
baseURL,
timeout: 10000
})
// 2. 请求拦截器,携带 token
instance.interceptors.request.use(
(config) => {
// 从pinia获取token
const store = useUserStore()
if (store.user?.token && config.headers) {
config.headers['Authorization'] = `Bearer ${store.user?.token}`
}
return config
},
(err) => Promise.reject(err)
)
// 3. 响应拦截器,剥离无效数据,401 拦截
instance.interceptors.response.use(
(res) => {
// 后台约定,响应成功,但是 code 不是 10000,是业务逻辑失败
if (res.data?.code !== 10000) {
// showToast(res.data?.message || '网络异常')
showToast(res.data?.message || '网络异常')
return Promise.reject(res.data)
}
// 业务逻辑成功,返回响应数据,作为 axios 成功的结果
return res.data
},
(err) => {
// token失效
if (err.response.status === 401) {
// 删除用户信息
const store = useUserStore()
store.delUser()
// 跳转登录,带上接口失效所在页面的地址,登录完成后回跳使用
router.push(`/login?returnUrl=${router.currentRoute.value.fullPath}`)
}
return Promise.reject(err)
}
)
// 通用的请求工具函数,支持设置响应数据类型。
const request = <T>(
url: string,
method: Method = 'get',
submitData?: object
) => {
return instance<T, { code: number; data: T; message: string }>({
url,
method,
// data, params
[method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData
})
}
export { baseURL, instance, request }
在要发请求的文件使用
// 引入上面封装好的方法
import { request } from '@/utils/request'
// 定义的泛型
import type { User } from './types/user'
// 引入pinia的方法
import { useUserStore } from './stores'
const hLogin = async () => {
const data = {}
// 发请求
const res = await request<User>('/login/password', 'post', data)
console.log(res.data)
// 存入pinia
userStore.setUser(res.data)
}