1.创建一个新的axios实例
2.请求拦截器,如果有token进行头部携带
3.响应拦截器a.剥离无效数据b.处理token失效
4.导出一个函数,调用当前的axios实例发请求,返回值promise
import axios, { AxiosError, type Method } from 'axios'
import { useUserStore } from '@/stores/user' //pinia存储
import router from '@/router'
import { showToast } from 'vant'
//导出基准地址,原因:其他地方不是通过axios发请求的地方用上基准地址
const baseURL = 'https://consult-api.itheima.net/'
const instance = axios.create({
//axios的一些配置,baseUrl timeoutbaseURL,// 基础地址。超时时间timeout: 10000
})
// 请求拦截器,携带toekn
instance.interceptors.request.use(
//config是请求配置(config) => {const store = useUserStore()if (store.user?.token && config.headers) {
//请求头设置tokenconfig.headers['Authorization'] = `Bearer ${store.user?.token}`}return config},(err) => Promise.reject(err)
)
// 响应拦截器 ,剥离无效数据,401拦截
instance.interceptors.response.use((res) => {// 后台约定,响应成功,但是code不是10000,是业务逻辑失败if (res.data?.code !== 10000) {showToast(res.data?.message || '业务失败')return Promise.reject(res.data)}// 业务逻辑成功,返回成功数据,作为axios成功的结果return res.data},(err) => {if (err.response.status === 401) {// 删除用户信息const store = useUserStore()store.delUser()// 跳转登录,带上接口失效所在页面的地址,登录完成后回跳使用router.push({path: 'login',// 将当前页面的完整路径作为值存储在"returnUrl"键下query: { returnUrl: router.currentRoute.value.fullPath }})}return Promise.reject(err)}
)type Data<T> = {code: numbermessage: stringdata: T
}// 4. 请求工具函数
const request = <T>(url: string,method: Method = 'get',submitData?: object
) => {// request<数据类型,数据类型>() 这样才指定了 res.data 的类型return instance.request<T, Data<T>>({url,method,
//1.如果是get请求,需要使用params来传递submitData ?a=10&c=10
//2.如果不是get请求,需要使用data传递submitData 请求体传参
//[]设置一个动态的key,写js表达式,js表达式的执行结果来当key
//methods参数:get,Get,GET转换成消息再来判断[method.toLocaleLowerCase() === 'get' ? 'params' : 'data']: submitData})
}
export { instance, baseURL, request }