在一个项目中务必会有很多的接口,如果很零散的写在文件里面就不方便维护了,在参考网上封装的各种案例后倒腾出来了一个对接口统一管理的封装:
1,下载axios
npm install axios -save
先看一下目录结构:
在api 目录下创建http.js(封装axios) ,ports.js(接口配置文件)
http.js
import axios from 'axios' // 引入axios
import qs from 'qs' // 序列化字符串
import store from '../store/store' // 引入全局状态管理
import router from '../router' // 路由
import { Toast } from 'vant' // 控件
// 环境切换
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = '//localhost:8082'
} else if (process.env.NODE_ENV === 'debug') {
axios.defaults.baseURL = '测试环境'
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = '生产环境'
}
// 请求超时时间
axios.defaults.timeout = 10000
let Base = '/vip'
function headerUrl (url) {
url = Base + url
return url
}
// post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// request 请求拦截器
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
const token = store.state.token
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
})
// response 响应拦截器
axios.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 服务状态码不是200的情况
error => {
if (error.response.status) {
switch (error.response.status) {
// 401 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login',
query: {redirect: router.currentRoute.fullPath}
})
break
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
Toast({
message: '登录过期,请重新登录',
duration: 1000,
forbidClick: true
})
localStorage.removeItem('token')
store.commit('loginSuccess', null)
// 跳转登录页面,并将要浏览的页面fullpath传过去,登录成功后跳转到要访问的页面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}, 1000)
break
// 404 请求不存在
case 404:
Toast({
message: '网络请求不存在',
duration: 1500,
forbidClick: true
})
break
// 其他错误直接抛出错误提示
default:
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
})
}
return Promise.reject(error.response)
}
}
)
export default {
/**
* get方法对应get请求
* @param {String}url 请求地址
* @param {Object}params携带参数
* @returns {Promise}
*/
get (url, params) {
return new Promise((resolve, reject) => {
axios.get(headerUrl(url), {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
},
/**
* post方法对应post请求
* @param {String} url 请求地址
* @param {Object} params 携带参数
* @returns {Promise}
*/
post (url, params) {
return new Promise((resolve, reject) => {
console.log(headerUrl(url))
axios.post(headerUrl(url), qs.stringify(params))
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
}
前面的文章讲解到了对全局状态管理的封装store
ports.js
接口配置文件
export default {
sign: {
login: '/public/login.do' // 后端登录接口
},
getData: {
...
}
}
将这两个文件引入main.js文件
// 接口封装,请求拦截
import ports from './api/ports.js'
import http from './api/http.js'
Vue.prototype.$ports = ports
Vue.prototype.$http = http
- 接下来就可以使用了:
methods: {
login (name) {
this.$http.post(this.$ports.sign.login, {
user: this.formInline.user,
passwd: this.formInline.password
}, res => {
if (res.success) {
this.$Message.success('Success!')
} else {
this.$Message.error('Fail!')
}
})
}
}