安装
npm i axios
说明一下:这里为啥没有写--save-dev
或--save
,看到这两个顾名思义,有dev
的是开发阶段需要的依赖,然而该命令会默认的直接下载成必须的依赖,也就是--save
,下载后,会在package.json
的dependencies
对象下,我下载的版本是^0.24.0
,暂时先不用管这个版本号了,我只是想记录下我在现在用的是哪个版本了
封装如下[亲测有效]
utils/http.js
//utils/http.js
import axios from 'axios' // 引入axios,交互,必须
import store from '@/store/store.js'//vuex的内容,我这里是想获取我存到vuex的token,按需
import router from '@/router/router_config.js'//路由,在登录失效时方便跳转到登录页面的,按需
// import qs from 'qs'//我在项目中没有用这个哦,按需吧
const Configuration = require('../../domain.js')//关于loading相关的配置变量定义,Configuration 是module.exports导出的,按需
// axios的一些配置,比如发送请求显示loading,请求回来loading消失之类的
const loadings = Configuration.config.showloading
const domains = Configuration.config
//获取token
const getTokenStorage = () => {
let token = ''
try {
if (store.state.token !== '') {
token = store.state.token
} else {
token = localStorage.getItem('token')
}
// console.log(token)
} catch (e) {
// TODO handle the exception
}
return token
}
/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {
$vm.$alert('去登录?', '提示', {
showClose: false,
confirmButtonText: '确定',
type: 'warning'
}).then(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
domains.isNoLogin = 1
})
}
/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, msg) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页// 403 token过期
// // 清除token并跳转登录页
case 401:
case 403:
if (domains.isNoLogin == 1) {
domains.isNoLogin = 0
$errMsg(msg)
store.dispatch('commitUserInfo', {})
localStorage.clear()
toLogin()
}
break
// 404请求不存在
case 404:
$errMsg('请求的资源不存在')
break
default:
console.log(msg)
}
}
/*
isNoLogin: 1,//是否允许执行跳转到登录
//loading的变量可以参考
showloading: {
loadingInstance: null, // loadin实例
timeId: null,
showLoading: true,
requestTime: 9000,
loadingTime: 900, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
loadingText: '加载中...' // 请求loading中的文字提示
}
*/
//展示loading,我的需要依赖element-ui
const showLoading = () => {
if (loadings.showLoading && !loadings.timeId) {
loadings.timeId = setTimeout(() => {
loadings.loadingInstance = $vm.$loading({
fullscreen: true,
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
loadings.timeId = null
console.log('加载ing-------------')
// 设置定时器时间
}, loadings.loadingTime)
}
}
//关闭loading
const hideLoading = () => {
clearTimeout(loadings.timeId)
loadings.timeId = null
if (loadings.loadingInstance) {
$vm.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
loadings.loadingInstance.close()
})
}
}
var service = axios.create({
timeout: loadings.requestTime,//请求超时时间
baseURL: '/api', // (process.env.NODE_ENV !== 'production' ? '/api' : '/'),
headers: {
/* post:{
'Content-Type': 'application/x-www-form-urlencoded'
} */
}
})
service.interceptors.request.use((config) => { // 配置发送请求的信息
const tokenRes = getTokenStorage()
config.headers = {
...config.headers,
// 'Content-Type': 'application/x-www-form-urlencoded',
token: tokenRes
}
// console.log(config)
/* if (config.method == 'get') {
console.log("get")
config.data.token = tokenRes;
} else if (config.method == 'post') {
console.log("post")
config.data.token = tokenRes;
// config.data = qs.stringify(config.data);
// config.params = config.data;
} */
// console.log("环境参数:", process.env.NODE_ENV);
if (config.url.indexOf('?') > -1) {
config.url = config.url + `&n=${encodeURIComponent(Math.random())}`
} else {
config.url = config.url + `?n=${encodeURIComponent(Math.random())}`
}
showLoading()
return config
}, function (error) {
return Promise.reject(error)
})
service.interceptors.response.use((res) => { // 配置请求回来的信息
hideLoading()
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
if (res.status === 200) {
return res.data
} else {
return Promise.reject(res)
}
}, (error) => {
hideLoading()
const {
response
} = error
if (response) {
// 请求已发出,但是不在2xx的范围
errorHandle(response.status, response.data.data)
return Promise.reject(response)
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
if (!window.navigator.onLine) {
store.commit('changeNetwork', false)
} else {
return Promise.reject(error)
}
}
})
export default service
如何使用service呢?
先引入,以及请求的方法
api/index.js
//api/index.js
import service from '@/utils/http.js'
// 登录,post请求参考
function toLogin (params) {
return service.post('user/tologin', params)
}
//获取字典数据,get请求参考
function getCombo(params) {
return service.get(`combo/getCombo`, {
params
})
}
export default {
toLogin,getCombo
}
main.js
import Vue from 'vue'
import api from './api'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import jsCookie from 'js-cookie'
Vue.use(ElementUI);
Vue.prototype.$http = api // 其他页面在使用axios的时候直接 this.$http就可以了
Vue.prototype.$cookie = jsCookie
页面中调用如下
login.vue
async dologin(){
let res = await this.$http.toLogin(data);
if(!res.success){
this.$message({
type: 'error',
message: '用户名或密码错误'
});
return
}
//登录成功后做登录的事。。。。
this.$router.replace({
path: `/home`
})
}