# axios
axios
文档地址:http://www.axios-js.com (opens new window)
# 项目中的封装
axios
的封装方式网上多如牛毛,可以根据自己的业务进行适合的封装,以提高代码复用率与维护便捷度。
以下是本项目对 axios
的封装
import axios from 'axios'
import store from '@/store'
import router from '@/router'
import { HOST } from '@/config'
import MindUI from 'mind-ui-vue'
const Toast = MindUI.Toast // 提示组件
// axios 配置
axios.defaults.timeout = 20000 // 接口超时时长 20s
axios.defaults.baseURL = HOST // 接口域名
axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8'
// 请求时的拦截
axios.interceptors.request.use(config => {
// 登录成功后 token 信息会存入到 localStorage 和 vuex 中
// 如果 store 中存在 token,则请求时携带上
// 如果后端接口不需要传入 token,后端接口会直接忽略
if (store.state.user.token) {
config.headers['Authorization'] = 'Bearer ' + store.state.user.token
}
return config
}, function (error) {
return Promise.reject(error)
})
// 返回值
axios.interceptors.response.use(res => {
if (res.status === 200) {
// 接口内部定义状态码,大于400则为接口出错、参数错误等
if (res.data.code >= 400) {
Toast({
position: 'top',
message: res.data.message
})
}
return res.data
}
// 此处接口只要有返回,无论是什么错误,都重新整理为以下通用格式
return {
code: res.status_code,
message: res.message,
data: {}
}
}, error => {
if (String(error).includes('timeout')) {
Toast('网络请求超时')
} else if (String(error).includes('Network Error')) {
// 网络异常,则跳转到离线页面
router.push({
path: '/offline'
})
} else if (error.response) {
const { status, statusText } = error.response
// 此处为后端定义的未登录状态
// 未登录则清除用户信息的缓存
if (status === 401) {
// 清空用户信息
store.commit("user/SET_USER", null);
store.commit("user/SET_TOKEN", "");
localStorage.removeItem("user");
localStorage.removeItem("token");
// 以下页面未登录时,不需要重定向到登录页
if (!['Login', 'Profile', 'Register', 'NotFound', 'Forget'].includes(router.currentRoute.name)) {
router.push({
path: '/login',
query: { redirect: router.currentRoute.fullPath }
})
}
return error.response.data
}
// 接口异常提示,无需在接口使用地方再次判断做处理
Toast(status + '' + statusText)
}
// 后端无返回时,组装一个返回错误的数据,不然 await 后的代码无法运行,
// 导致后面的 this.loading 等方法无法执行,页面停留在加载状态
// 也可以给每个请求包裹 try catch 处理,但是会麻烦
return {
'code': 400,
'messsage': 'error'
}
})
// 导出请求方法
export default {
get(url, params) {
return axios({
method: 'get',
url,
params
})
},
post(url, data) {
return axios({
method: 'post',
url,
data
})
},
patch(url, data) {
return axios({
method: 'patch',
url,
data
})
},
put(url, data) {
return axios({
method: 'put',
url,
data
})
},
delete(url, data) {
return axios({
method: 'delete',
url,
data
})
}
}
# 接口定义
// 导入封装的 axios 文件并命名为 http
import http from '@/http/index'
// 定义一个获取影视评论的接口
export const getMovieComments = (id, params) => http.get(`/movies/${id}/comments`, params);
# 接口使用
import { getMovieComments } from "@/api/movie";
...
data() {
return {
loading: false,
list: [],
page: 1,
total: 0
}
},
mounted() {
this.getMovieComments();
},
methods: {
async getMovieComments() {
this.loading = true;
let params = {
page: this.page
}
let {code, data, total } = await getMovieComments(id, params);
if(code === 200) {
this.page++;
this.list.push(...data);
this.total = total;
}
this.$nextTick(() => {
this.loading = false;
})
}
}