前后端交互是最基础的功能,本文所说是我在最近一个项目中对API和请求的封装,这些对每个项目来说都是必须的,下面分享我的一些简化方法。 首先是对API的封装,先来看目录结构:
在modules目录中存放的是各个模块的api,axios.js是对全局请求的封装,apiList.js中主要用于动态导入一组模块,并将它们作为对象的属性存储在 API 对象中,这是为了相关的模块统一管理,统一使用。
// apiList.js
const req = import.meta.globEager('./modules/*.js')
const api = {}
for (const key in req) {
const name = key.replace(/^\.\/modules\/(.*)\.\w+$/, '$1')
const value = req[key]
api[name] = value.default
}
const API = api
export default API
- 首先,使用vite的import.meta.globEager方法来动态导入以 .js 结尾的所有模块文件。这会返回一个对象,其中键是模块路径,值是模块的内容。
- 第二步,遍历导入的模块对象中的键,name中使用正则表达式将模块路径转换为模块的名称(即去除路径和文件扩展名),value则是获取模块的内容。
- 第三步,api[name] = value.default,是将模块的默认导出赋值给
api对象的属性,属性名为模块的名称,再将API对象作为默认导出。
在modules目录下,我们可以把模块命名为一个变量,再默认导出,如:
// user.js
import http from '../axios'
const admin = {
getInfo(data) {
return http({
url: '/login/getUserInfo',
method: 'get',
params: data
})
}
}
export default admin
然后在main.js中引入挂载到全局:app.config.globalProperties.$API = API
在组件中只需要通过getCurrentInstance()函数获取实例,然后引用即可,例:
const API = getCurrentInstance().proxy.$API
API.user.getInfo(data)
在就是对请求的封装
import axios from 'axios'
import {
getToken,
...
} from '@/core/auth.js'
import baseURL from './url'
import Router from '../router'
import { ElMessage } from 'element-plus'
// 创建实例
const http = axios.create({
baseURL,
timeout: 15000
})
// 设置post请求头
http.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded'
// http.defaults.withCredentials = true //是否携带密钥信息
// 请求拦截 -->在请求发送之前做一些事情
http.interceptors.request.use(
config => {
config.headers.Authorization = getToken() || ''
...
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截 -->在返回结果之前做一些事情
http.interceptors.response.use(
response => {
const data = response.data
// 其他
if (data.status === 200 || data.success) {
return data.data || data.object
} else if (data.resCode === '10000') {
// 登录过期
Router.replace({ path: '/loginIndex' })
removeInfo()
return Promise.reject(response.data)
} else {
ElMessage({
message: data.message || data.msg,
type: 'error',
duration: 2000
})
return Promise.reject(response.data)
}
},
error => {
const data = error.response
if (data && data.status === 403) {
return Promise.reject(error)
}
if (data && data.status === 500) {
ElMessage({
message: '服务器出小差了,稍后重试~',
type: 'error',
duration: 2000
})
}
return Promise.reject(error)
}
)
export default http
这是一些常见的对请求的封装,对一些错误请求也都做了处理。
当然有些特殊的需求,比如取消请求可以创建一个取消请求CancelToken实例,当然我在这个项目中没有用到