pnpm install axios
import router from '@/router'
import { useUserStore } from './../stores/modules/user'
import axios from 'axios'
import { showToast } from 'vant'
const instance = axios.create({
// 1. 基础地址,超时时间
baseURL: 'xxx',
timeout: 30000
})
instance.interceptors.request.use(
(config) => {
// 2. 携带token
const userStore = useUserStore()
if (userStore.user?.token && config.headers) {
config.headers.Authorization = `Bearer ${userStore.user.token}`
}
return config
},
(err) => Promise.reject(err)
)
instance.interceptors.response.use(
(res) => {
// 3. 处理业务失败
if (res.data?.code !== 10000) {
// 提示错误信息
showToast(res.data.message || '业务失败')
// 返回接口返回值
return Promise.reject(res.data)
}
// 4. 摘取核心响应数据
return res.data
},
(err) => {
// 5. 处理401错误
if (err.response.status === 401) {
// 清除token
const userStore = useUserStore()
userStore.delUser()
// 跳转login 并且携带当前页面的地址和参数(目的是登陆之后,再次跳转到当前页面,交互良好)
router.push({
path: '/login',
query: { returnUrl: router.currentRoute.value.fullPath }
})
}
return Promise.reject(err)
}
)
export default instance
get请求:axios.request({url,methos,params})
post请求:axios.request({url,methos,data})
以上两种请求方式除了参数方式不一样,其他的都一样,基于此,进行第二次封装
import axios, { AxiosError, type Method } from 'axios'
// 工具函数
const request = (url: string, method: Method = 'GET', submitData?: object) => {
return instance.request({
url,
method,
[method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData
})
}
// 这个需要替换axsio.request默认的响应成功后的结果类型
// 之前是:传 { name: string } 然后res是 res = { data: { name: string } }
// 但现在:在响应拦截器中返回了 res.data 也就是将来响应成功后的结果,和上面的类型一致吗?
// 所以要:request<数据类型,数据类型>() 这样才指定了 res.data 的类型
// 但是呢:后台返回的数据结构相同,所以可以抽取相同的类型
type Data<T> = {
code: number
message: string
data: T
}
// 请求工具函数
const request = <T>(url: string, method: Method = 'get', submitData?: object) => {
return instance.request<any, Data<T>>({
url,
method,
[method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
})
}
const getUser = async () => {
await request('xx')
}
const login = async () => {
await request<User>('xx', 'post', {
password: 'abc12345',
mobile: '13211112222'
})