vue-cli3学习之-axios封装
1,准备地址 baseUrl
根据生产与开发环境来改变不同的地址,新建env.js。
此处的 ‘/api’ 是在vue.config.js里配置的地址
(参考vue-cli3学习之-vue.config.js配置)
let baseUrl = '';
if (process.env.NODE_ENV == 'development') {
baseUrl = '/api';
} else if (process.env.NODE_ENV == 'production') {
//baseUrl = '测试地址';
//baseUrl = '预发布地址';
baseUrl = '生产地址';
}
export {
baseUrl,
}
2,axios请求封装
封装的前提,你至少得把axios引入吧!在此不多说了
在你的项目中应该有一个plugins文件,里面应该有一个axios.js文件,有的话就打开他,没有的话,那就新建一个吧!
2-1,这是你需要引入的东西
import {
baseUrl, //引入baseUrl
} from "../plugins/env";
import axios from 'axios';
import qs from 'qs'
import { Loading, Message } from 'element-ui'
import router from '../router'
2-2,基本的配置与取值,当然,你也可以把值存在store里,你开心就好
axios.defaults.timeout = 10000; //设置请求时间
axios.defaults.baseURL = baseUrl;//设置默认接口地址
axios.defaults.headers = { 'Content-Type': 'application/json; charset=utf-8' };
let loadinginstace = '';
let token = localStorage.getItem('token'); //从localstorage取值
2-3,http请求拦截器
axios.interceptors.request.use(
config => {
loadinginstace = Loading.service({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.3)',
customClass: "osloading",
fullscreen: true
})
if (token) {
config.headers['X-Token'] = getToken()
}
if (config.method === 'post' || config.method === 'put' || config.method === 'delete') {
config.data = qs.stringify(config.data)
}
return config
},
error => {
loadinginstace.close();
return Promise.reject(error)
}
)
2-4,http response 服务器响应拦截器
axios.interceptors.response.use(res => {
loadinginstace.close()
if (res.data === '' || res.data.length === 0 || res.data === 'undefined' || res.data === undefined) {
Message({
type: 'error',
message: '数据可能走丢了!'
})
}
return res.data
},
error => {
loadinginstace.close()
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
Message({
type: 'error',
message: '请求超时!'
})
}
const errorInfo = error.response
if (errorInfo) {
if (errorInfo.status === 401) {
router.push({
path: '/login'
})
}
}
return Promise.reject(error)
}
);
2-5,get,post请求简单封装
export function fetch(url, params = {}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err)
})
})
}
export function post(url, data = {}) {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then(response => {
resolve(response.data);
}, err => {
reject(err)
})
})
}
2-5,在main.js中引入,就可以用了
import { post, fetch } from "./plugins/axios";
Vue.prototype.$get=fetch;
Vue.prototype.$post=post;
使用例子
this.$post("/login",{"password": "admin","username": "admin"}).then((res)=>{
console.log(res)
})
以下是全部代码
import {
baseUrl, //引入baseUrl
} from "../plugins/env";
import axios from 'axios';
import qs from 'qs'
import { Loading, Message } from 'element-ui'
import router from '../router'
axios.defaults.timeout = 10000; //设置请求时间
axios.defaults.baseURL = baseUrl;//设置默认接口地址
axios.defaults.headers = { 'Content-Type': 'application/json; charset=utf-8' };
let loadinginstace = '';
let token = localStorage.getItem('token'); //从localstorage取值
// http请求拦截器
axios.interceptors.request.use(
config => {
// element ui Loading方法
loadinginstace = Loading.service({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.3)',
customClass: "osloading",
fullscreen: true
})
if (token) {
config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
}
// 判断为post请求,序列化传来的参数
if (config.method === 'post' || config.method === 'put' || config.method === 'delete') {
config.data = qs.stringify(config.data)
}
return config
},
error => {
loadinginstace.close();
return Promise.reject(error)
}
)
// http response 服务器响应拦截器,
axios.interceptors.response.use(res => {
// 请求成功时要做的处理
// 对响应数据做些事,把loading动画关掉
loadinginstace.close()
// 对请求成功的值进行统一判断
// 1.判空
if (res.data === '' || res.data.length === 0 || res.data === 'undefined' || res.data === undefined) {
Message({
type: 'error',
message: '数据可能走丢了!'
})
}
// 2.错误提示(前提是接口跑通了,只是对里边某些值做下详细判断。要先跟后台商定好,对某个固定的字段进行判断,并且确定固定字段来承接 错误信息,方便展示)
// if (res.data && !res.data.success) {
// console.log(res.data.error.message)
// }
return res.data
},
error => {
loadinginstace.close()
// 1.判断请求超时
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
Message({
type: 'error',
message: '请求超时!'
})
// return service.request(originalRequest);//例如再重复请求一次
}
// 2.需要重定向到错误页面
const errorInfo = error.response
if (errorInfo) {
// error =errorInfo.data//页面那边catch的时候就能拿到详细的错误信息,看最下边的Promise.reject
if (errorInfo.status === 401) {
router.push({
path: '/login'
})
}
// if (errorInfo.status === 500) {
// router.push({
// path: "/error/500"
// });
// }
// if (errorInfo.status === 502) {
// router.push({
// path: "/error/502"
// });
// }
// if (errorInfo.status === 404) {
// router.push({
// path: "/error/404"
// });
// }
}
return Promise.reject(error)
}
);
/**
* 封装get方法
* @param url
* @param data
* @returns {Promise}
*/
export function fetch(url, params = {}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err)
})
})
}
/**
* 封装post请求
* @param url
* @param data
* @returns {Promise}
*/
export function post(url, data = {}) {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then(response => {
resolve(response.data);
}, err => {
reject(err)
})
})
}