1. 配置 axios 實例參數(shù)和攔截處理
新建 src/utils/request.js ,代碼如下
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
function errorTips(err) {
Message({
message: err.message || '請求失敗',
type: 'error',
duration: 3000,
})
}
/*************************** 全局默認配置 ************************************/
// // post請求頭
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// // 請求超時時間
// axios.defaults.timeout = 5000
// // 允許攜帶cookie
// axios.defaults.withCredentials = true
// // 完整url = base url + request url
// axios.defaults.baseURL = process.env.VUE_APP_BASE_API
/*************************** 實例默認配置 (多服務(wù)可創(chuàng)建多個實例)************************************/
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
// baseURL: process.env.NODE_ENV === 'production' ? './' : '/', // 如果前端和后端服務(wù)在同服務(wù)器環(huán)境下可這樣配置
timeout: 5000,
withCredentials: true,
headers: {
post: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
},
},
})
// 請求攔截
service.interceptors.request.use(
config => {
// 可在此配置 loading 加載動畫
const token = store.state.user.token
if (token) {
config.headers.Authorization = token
}
return config
},
error => {
return Promise.reject(error)
}
)
// 響應(yīng)攔截
service.interceptors.response.use(
response => {
// 可在此配置 loading 加載結(jié)束
const res = response.data
if (res.code !== 0) {
errorTips(res)
if (res.code === 401 || res.code === 403 || res.code === 404) {
MessageBox.confirm('登錄超時,請重新登錄', {
confirmButtonText: '確認',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '請求錯誤'
break
case 401: {
error.message = '未授權(quán),請登錄'
const router = this.$router
router.replace({
path: 'login',
query: {
redirect: router.currentRoute.path,
},
})
break
}
case 403:
error.message = '沒有權(quán)限,拒絕訪問'
break
case 404:
error.message = `請求地址出錯`
break
case 408:
error.message = '請求超時'
break
case 500:
error.message = '服務(wù)器內(nèi)部錯誤'
break
case 501:
error.message = '服務(wù)未實現(xiàn)'
break
case 502:
error.message = '網(wǎng)關(guān)錯誤'
break
case 503:
error.message = '服務(wù)不可用'
break
case 504:
error.message = '網(wǎng)關(guān)超時'
break
case 505:
error.message = 'HTTP版本不受支持'
break
default:
break
}
}
errorTips(error)
return Promise.reject(error)
}
)
export default service
2. 封裝請求 API
新建 src/api/user.js ,代碼如下
// 用戶模塊
import request from '@/utils/request'
export function login(data) {
return request({
url: '/api/user/login',
method: 'post',
data,
})
}
export function getInfo(params) {
return request({
url: '/api/user/info',
method: 'get',
params,
})
}
export function logout(data) {
return request({
url: '/api/user/logout',
method: 'post',
data,
})
}
3. 在組件中使用
方式一:直接在組件中使用
import { getInfo } from '@/api/user'
// 在 methods 中
getUserInfo() {
const token = this.state.token
getInfo({token}).then(res => {
if(res.errorCode === '0'){
console.log(res.data)
const { name, avatar } = res.data
}else{
console.log('獲取信息失敗')
}
},
方法二:在 Vuex 中使用
- 在 src/store/modules/user.js 中調(diào)用 API
import { login } from '@/api/user'
// 用戶登錄
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password })
.then(response => {
const { data } = response
commit('setToken', data.token)
setToken(data.token)
resolve()
})
.catch(error => {
reject(error)
})
})
},
- 在組件中調(diào)用 store 下的 user 模塊下的 actions 下的 login 方法
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store
.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || '/' })
this.loading = false
})
.catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
},