目的
嘗試封裝Axios瞒滴,并集中管理接口姨夹。目的是進(jìn)一步提高項(xiàng)目的可維護(hù)性夸溶。
思路
- 確保項(xiàng)目中已經(jīng)安裝了Axios
- 在request.js文件中導(dǎo)入Axios吴旋,封裝后導(dǎo)出給api.js损肛;
- 在api.js文件中導(dǎo)入request.js中封裝好的請(qǐng)求,定制接口荣瑟,隨后導(dǎo)出治拿;
- 在頁(yè)面中使用api.js暴露出的接口。
有思路了可以首先改造項(xiàng)目目錄笆焰,在/src文件夾新建request文件夾劫谅,同時(shí)在此創(chuàng)建兩個(gè)文件,分別是:
- request.js (用來(lái)管理Axios請(qǐng)求)
-
api.js (用來(lái)管理API接口)
封裝Axios請(qǐng)求
在request.js文件中導(dǎo)入axios
導(dǎo)入qs嚷掠,暫時(shí)只知道這個(gè)是用來(lái)序列化字符串的庫(kù)
有需要的話捏检,導(dǎo)入輕提示UI組件 toast
導(dǎo)入vuex store因?yàn)閿r截請(qǐng)求前奸例,要驗(yàn)證里面的狀態(tài)對(duì)象
導(dǎo)入路由迎变,用于解決跳轉(zhuǎn)
import axios from 'axios'
import QS from 'qs'
import { Toast } from 'vant'
import store from '@/store'
import router from '@/router'
環(huán)境配置
// 分別配置開發(fā)、調(diào)試鸭叙、發(fā)布時(shí)請(qǐng)求的根地址
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'debug') {
axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = ''
}
請(qǐng)求的基本配置
// 設(shè)置鏈接超時(shí)時(shí)長(zhǎng)
axios.defaults.timeout = 1000 * 5
// 設(shè)置post請(qǐng)求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
請(qǐng)求的攔截
axios.interceptors.request.use(
config => {
// 請(qǐng)求前判斷token是否存在霹娄,如果存在能犯,再請(qǐng)求的header都加上token
const token = store.state.token
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
}
)
返回的攔截
axios.interceptors.response.use(
response => {
// 如果狀態(tài)200鲫骗,請(qǐng)求成功,否則拋出錯(cuò)誤
if (response.status === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 根據(jù)后臺(tái)錯(cuò)誤狀態(tài)碼進(jìn)行操作
// 以下是常規(guī)操作踩晶,其他需求自行拓展
error => {
if (error.response.status) {
switch (error.response.status) {
// 401 未登錄
case 401:
// 跳轉(zhuǎn)到登陸頁(yè)面执泰,并攜帶當(dāng)前頁(yè)面路徑
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
break
// 403 token過(guò)期
case 403:
// 做出提示
Toast({
message: '403登陸信息異常,請(qǐng)重新登陸'
})
// 清除本地token
localStorage.removeItem('token')
// 清除vuex中的token對(duì)象
store.commit('loginSucsess', null)
// 1秒后渡蜻,跳轉(zhuǎn)到登陸頁(yè)面坦胶,并攜帶當(dāng)前頁(yè)面路徑
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}, 1000)
break
// 404請(qǐng)求不存在
case 404:
Toast({
message: '404請(qǐng)求不存在'
})
break
default:
// 提示信息
Toast({
message: error.response.data.message
})
}
return Promise.reject(error.response)
}
}
)
封裝并導(dǎo)出get方法
export function get (url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
封裝并導(dǎo)出post方法
這里有個(gè)問(wèn)題要注意,axios.get()方法和axios.post()在提交數(shù)據(jù)時(shí)參數(shù)的書寫方式還是有區(qū)別的晴楔。get的第二個(gè)參數(shù)是一個(gè)對(duì)象,這個(gè)對(duì)象的params屬性值是參數(shù)對(duì)象峭咒。而post的第二個(gè)參數(shù)直接就是一個(gè)參數(shù)對(duì)象税弃。
export function post (url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
API統(tǒng)一管理
在api.js文件中,導(dǎo)入request.js中封裝好的get方法
import { get } from './request.js'
把接口暴露出去
// 如果有必要凑队,把跟地址單獨(dú)處理
const baseUrl = 'https://your_api_base_url.com'
// 定義接口则果,然后暴露出去
export const apiName = (params) => get(baseUrl + '/your_api_adress', params)
在需要使用接口的地方
// 導(dǎo)入接口
import { apiName } from '@/request/api.js'
// 使用接口
apiName(params)
.then(res => {
// 成功后的操作
})
.catch(res => {
// 失敗后的操作
})