vue axios基于常見業(yè)務場景的二次封裝的實現(xiàn)
axios
axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
在前端框架中的應用也是特別廣泛,不管是vue還是react,都有很多項目用axios作為網(wǎng)絡請求庫。
我在最近的幾個項目中都有使用axios,并基于axios根據(jù)常見的業(yè)務場景封裝了一個通用的request服務。
npm:
$ npm install axios
bower:
$ bower install axios
Using cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
業(yè)務場景:
- 全局請求配置。
- get,post,put,delete等請求的promise封裝。
- 全局請求狀態(tài)管理,供加載動畫等使用。
- 路由跳轉(zhuǎn)取消當前頁面請求。
- 請求攜帶token,權(quán)限錯誤統(tǒng)一管理。
默認配置
定義全局的默認配置
axios.defaults.timeout = 10000 //超時取消請求 axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8' axios.defaults.baseURL = process.env.BASE_URL
自定義配置(非常見業(yè)務場景,僅作介紹)
// 創(chuàng)建實例時設置配置的默認值
var instance = axios.create({
baseURL: 'https://api.another.com'
});
// 在實例已創(chuàng)建后修改默認值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
優(yōu)先級:自定義配置 > 默認配置
請求及響應攔截器
請求攔截器
// 請求列表
const requestList = []
axios.interceptors.request.use((config) => {
//1.將當前請求的URL添加進請求列表數(shù)組
requestList.push(config.url)
//2.請求開始,改變loading狀態(tài)供加載動畫使用
store.dispatch('changeGlobalState', {loading: true})
//3.從store中獲取token并添加到請求頭供后端作權(quán)限校驗
const token = store.getters.userInfo.token
if (token) {
config.headers.token = token
}
return config
}, function (error) {
return Promise.reject(error)
})
1.請求攔截器中將所有請求的url添加進請求列表變量,為取消請求及l(fā)oading狀態(tài)管理做準備
2.請求一旦開始,就可以開啟動畫加載效果。
3.用戶登錄后可以在請求頭中攜帶token做權(quán)限校驗使用。
響應攔截器
axios.interceptors.response.use(function (response) {
// 1.將當前請求中請求列表中刪除
requestList.splice(requestList.findIndex(item => item === response.config.url), 1)
// 2.當請求列表為空時,更改loading狀態(tài)
if (requestList.length === 0) {
store.dispatch('changeGlobalState', {loading: false})
}
// 3.統(tǒng)一處理權(quán)限認證錯誤管理
if (response.data.code === 900401) {
window.ELEMENT.Message.error('認證失效,請重新登錄!', 1000)
router.push('/login')
}
return response
}, function (error) {
// 4.處理取消請求
if (axios.isCancel(error)) {
requestList.length = 0
store.dispatch('changeGlobalState', {loading: false})
throw new axios.Cancel('cancel request')
} else {
// 5.處理網(wǎng)絡請求失敗
window.ELEMENT.Message.error('網(wǎng)絡請求失敗', 1000)
}
return Promise.reject(error)
})
1.響應返回后將相應的請求從請求列表中刪除
2.當請求列表為空時,即所有請求結(jié)束,加載動畫結(jié)束
3.權(quán)限認證報錯統(tǒng)一攔截處理
4.取消請求的處理需要結(jié)合其他代碼說明
5.由于項目后端并沒有采用RESTful風格的接口請求,200以外都歸為網(wǎng)絡請求失敗
promise封裝及取消請求
const CancelToken = axios.CancelToken
//cancel token列表
let sources = []
const request = function (url, params, config, method) {
return new Promise((resolve, reject) => {
axios[method](url, params, Object.assign({}, config, {
//1.通過將執(zhí)行程序函數(shù)傳遞給CancelToken構(gòu)造函數(shù)來創(chuàng)建cancel token
cancelToken: new CancelToken(function executor (c) {
//2.將cancel token存入列表
sources.push(c)
})
})).then(response => {
resolve(response.data)
}, err => {
if (err.Cancel) {
console.log(err)
} else {
reject(err)
}
}).catch(err => {
reject(err)
})
})
}
const post = (url, params, config = {}) => {
return request(url, params, config, 'post')
}
const get = (url, params, config = {}) => {
return request(url, params, config, 'get')
}
//3.導出cancel token列表供全局路由守衛(wèi)使用
export {sources, post, get}
1.axios cancel token API
2.存入需要取消的請求列表導出給導航守衛(wèi)使用
3.router.js
...
import { sources } from '../service/request'
...
router.beforeEach((to, from, next) => {
document.title = to.meta.title || to.name
//路由發(fā)生變化時取消當前頁面網(wǎng)絡請求
sources.forEach(item => {
item()
})
sources.length = 0
next()
})
request.js完整代碼:
// 引入網(wǎng)絡請求庫 https://github.com/axios/axios
import axios from 'axios'
import store from '../store'
import router from '../router'
// axios.defaults.timeout = 10000
const requestList = []
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
axios.defaults.baseURL = process.env.BASE_URL
// 自定義攔截器
axios.interceptors.request.use((config) => {
requestList.push(config.url)
store.dispatch('changeGlobalState', {loading: true})
const token = store.getters.userInfo.token
if (token) {
config.headers.token = token
}
return config
}, function (error) {
return Promise.reject(error)
})
axios.interceptors.response.use(function (response) {
requestList.splice(requestList.findIndex(item => item === response.config.url), 1)
if (requestList.length === 0) {
store.dispatch('changeGlobalState', {loading: false})
}
if (response.data.code === 900401) {
window.$toast.error('認證失效,請重新登錄!', 1000)
router.push('/login')
}
return response
}, function (error) {
requestList.length = 0
store.dispatch('changeGlobalState', {loading: false})
if (axios.isCancel(error)) {
throw new axios.Cancel('cancel request')
} else {
window.$toast.error('網(wǎng)絡請求失??!', 1000)
}
return Promise.reject(error)
})
const CancelToken = axios.CancelToken
let sources = []
const request = function (url, params, config, method) {
return new Promise((resolve, reject) => {
axios[method](url, params, Object.assign(config, {
cancelToken: new CancelToken(function executor (c) {
sources.push(c)
})
})).then(response => {
resolve(response.data)
}, err => {
reject(err)
}).catch(err => {
reject(err)
})
})
}
const post = (url, params, config = {}) => {
return request(url, params, config, 'post')
}
const get = (url, params, config = {}) => {
return request(url, params, config, 'get')
}
export {sources, post, get}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue 3 中watch 和watchEffect 的新用法
本篇文章主要通過 Options API 和 Composition API 對比 watch 的使用方法,讓大家快速掌握 vue3 中 watch 新用法,需要的朋友可以參考一下哦,希望對大家有所幫助2021-11-11
el-form resetFields無效和validate無效的可能原因及解決方法
本文主要介紹了el-form resetFields無效和validate無效的可能原因及解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

