vue中封裝axios并實(shí)現(xiàn)api接口的統(tǒng)一管理
在vue項(xiàng)目中,我們通常都是使用axios與后臺(tái)進(jìn)行數(shù)據(jù)交互,axios有很多好用的特性,這里不多做介紹,相關(guān)細(xì)節(jié)可以查閱axios中文網(wǎng)。在對axios進(jìn)行封裝之前,我們要使用vue腳手架工具創(chuàng)建一個(gè)vue項(xiàng)目(這里我用的是cli4)。
安裝
cnpm install axios --save-dev; // 安裝axios cnpm install qs --save-dev; // 安裝qs模塊,用來序列化post類型的數(shù)據(jù),否則后端無法接收到數(shù)據(jù)
模塊引入
在src目錄下創(chuàng)建一個(gè)service目錄,用于存放接口封裝的相關(guān)文件。然后在service目錄中創(chuàng)建service.js,用于axios、qs模塊的引入,并在此文件中對axios進(jìn)行封裝。代碼如下(接口域名只有一個(gè)的情況):
import axios from 'axios' //引入axios
import qs from 'qs' //引入qs,用來序列化post類型的數(shù)據(jù),否則后端無法接收到數(shù)據(jù)
// 設(shè)置post請求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.withCredentials = false;//在跨域請求時(shí),不會(huì)攜帶用戶憑證;返回的 response 里也會(huì)忽略 cookie
//創(chuàng)建axios實(shí)例,請求超時(shí)時(shí)間為300秒
const instance = axios.create({
timeout: 300000,
});
//請求和響應(yīng)攔截可以根據(jù)實(shí)際項(xiàng)目需求進(jìn)行編寫
// 請求發(fā)起前攔截
instance.interceptors.request.use((config) => {
//這里可以對接口請求頭進(jìn)行操作 如:config.headers['X-Token'] = token
console.log("請求攔截",config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
// 響應(yīng)攔截(請求返回后攔截)
instance.interceptors.response.use(response => {
console.log("響應(yīng)攔截",response);
return response;
}, error => {
console.log('catch', error)
return Promise.reject(error)
})
//按照請求類型對axios進(jìn)行封裝
const api={
get(url,data){
return instance.get(url,{params:data})
},
post(url,data){
return instance.post(url,qs.stringify(data))
},
}
export {api}
上述代碼是接口域名只有一個(gè)的情況(多數(shù)情況),當(dāng)接口域名有多個(gè)的時(shí)候(少數(shù)情況),我們需要對之前的封裝進(jìn)行改造,代碼如下:
import axios from 'axios' //引入axios
import qs from 'qs' //引入qs,用來序列化post類型的數(shù)據(jù),否則后端無法接收到數(shù)據(jù)
// 設(shè)置post請求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.withCredentials = false;//在跨域請求時(shí),不會(huì)攜帶用戶憑證;返回的 response 里也會(huì)忽略 cookie
//創(chuàng)建axios實(shí)例,請求超時(shí)時(shí)間為300秒,因?yàn)轫?xiàng)目中有多個(gè)域名,所以對應(yīng)的也要?jiǎng)?chuàng)建多個(gè)axios實(shí)例
const instanceA = axios.create({
timeout: 300000,
});
const instanceB = axios.create({
timeout: 300000,
});
//如果項(xiàng)目為單一域名,這里可以不用進(jìn)行配置,當(dāng)項(xiàng)目接口有多個(gè)域名時(shí),要對axios實(shí)例基礎(chǔ)路徑進(jìn)行配置,否則在項(xiàng)目生產(chǎn)環(huán)境中無法進(jìn)行區(qū)別調(diào)用
if (process.env.NODE_ENV == 'production') {
instanceA.defaults.baseURL = 'https://www.production_a.com';
instanceB.defaults.baseURL = 'https://www.production_b.com';
}
//請求和響應(yīng)攔截可以根據(jù)實(shí)際項(xiàng)目需求進(jìn)行編寫
// 請求發(fā)起前攔截
instanceA.interceptors.request.use((config) => {
//這里可以對接口請求頭進(jìn)行操作 如:config.headers['X-Token'] = token
console.log("請求攔截",config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
instanceB.interceptors.request.use((config) => {
console.log("請求攔截",config);
return config;
}, (error) => {
// Do something with request error
return Promise.reject(error)
})
// 響應(yīng)攔截(請求返回后攔截)
instanceA.interceptors.response.use(response => {
console.log("響應(yīng)攔截",response);
return response;
}, error => {
console.log('catch', error)
return Promise.reject(error)
})
instanceB.interceptors.response.use(response => {
console.log("響應(yīng)攔截",response);
return response;
}, error => {
console.log('catch', error)
return Promise.reject(error)
})
//按照請求類型對axios進(jìn)行封裝
const api={
get(url,data){
return instanceA.get(url,{params:data})
},
post(url,data){
return instanceA.post(url,qs.stringify(data))
},
doGet(url,data){
return instanceB.get(url,{params:data})
},
doPost(url,data){
return instanceB.post(url,qs.stringify(data))
}
}
export {api}
上述代碼中有根據(jù)生產(chǎn)環(huán)境對axios實(shí)例的基礎(chǔ)路徑進(jìn)行配置,如果項(xiàng)目中有多個(gè)環(huán)境(如:測試環(huán)境等),則需要對CLI4腳手架環(huán)境變量進(jìn)行配置
api接口統(tǒng)一管理
將api接口按照功能模塊進(jìn)行拆分,把同一模塊下的接口寫在同一個(gè)文件中進(jìn)行統(tǒng)一管理,這樣代碼會(huì)更容易維護(hù)。比如我們的項(xiàng)目中有新聞模塊,音樂模塊等。我們就在serviec目錄中創(chuàng)建news.js、music.js文件,用于管理各自模塊的所有api接口,這里我只拿news.js文件為例,代碼如下:
import {api} from "./service.js";
const news={
getNewsList(){//獲取新聞列表
return api.get("api/news/getNewsList")
},
editNewsDetail(data){//修改新聞詳情
return api.post("api/news/editNewsDetail",data);
}
}
export default news;
為了更方便在項(xiàng)目中調(diào)用這些封裝好的接口,我們需要將這些接口掛載到vue的原型上,首先我們要在service目錄中創(chuàng)建api.js文件,將所有模塊的api管理文件引入進(jìn)來,然后進(jìn)行統(tǒng)一導(dǎo)出,代碼如下:
//引入相關(guān)api管理模塊
import news from "./news.js";
//進(jìn)行統(tǒng)一導(dǎo)出
export default {
news
}
找到項(xiàng)目中的main.js文件,將接口掛載到vue的原型上,代碼如下:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
Vue.prototype.axios=axios
Vue.config.productionTip = false
import api from "./service/api.js";
//將封裝的接口掛載到vue原型上
Vue.prototype.$api = api;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
然后我們在項(xiàng)目創(chuàng)建完成時(shí)自動(dòng)生成的模板文件App.vue調(diào)用封裝好的接口,代碼如下:
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
<button @click="getN">接口封裝getN</button>
<button @click="postN">接口封裝postN</button>
</div>
<router-view/>
</div>
</template>
<script>
export default {
methods:{
getN(){
this.$api.news.getNewsList().then((res)=>{
console.log(res);
})
},
postN(){
let openid="oO5tQ5VMPpuzLqwfXhpmwjqwSANM";
let productCodes="pro-1337270496655446016";
this.$api.news.editNewsDetail({openid,productCodes}).then((res)=>{
alert(res.data.msg);
})
}
}
}
</script>
<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
配置代理
因?yàn)槲覀円诒镜丨h(huán)境進(jìn)行測試,這就涉及到了跨域問題,為了解決跨域問題,我們可以進(jìn)行代理的配置,在項(xiàng)目根目錄中創(chuàng)建vue.config.js文件,然后可以對項(xiàng)目進(jìn)行各種配置,代理的配置方法如下:
// vue.config.js
module.exports = {
// 輸出文件目錄
outputDir: "dist",
// eslint-loader 是否在保存的時(shí)候檢查
lintOnSave: false,
// 基本路徑
publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
devServer: {
host: "localhost",
port: 8080,
open: true,
hotOnly: true, // 熱更新
// 設(shè)置代理
proxy: {
"/api": {
// 本地mock服務(wù)器
target: "https://www.xxxx.com/xxx/",
changeOrigin: true,
ws: false,
},
//如果項(xiàng)目中存在多個(gè)域名接口,可依次進(jìn)行配置
"/apib":{
target: "https://www.xxxx.com/xxx/",
changeOrigin: true,
ws: false,
},
},
},
};
代理配置好了之后,就可以運(yùn)行項(xiàng)目了,命令行中輸入npm run serve,項(xiàng)目啟動(dòng)好了之后,就可以進(jìn)入頁面點(diǎn)擊按鈕,測試之前做的封裝是否好用。
結(jié)語
以上就是本人對vue中封裝axios的一點(diǎn)心得,文章有錯(cuò)誤或需要改進(jìn)的地方還請與我聯(lián)系,我將及時(shí)進(jìn)行更正,感謝閱讀。
以上就是vue中封裝axios并實(shí)現(xiàn)api接口的統(tǒng)一管理的詳細(xì)內(nèi)容,更多關(guān)于vue 封裝axios的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中的element tabs點(diǎn)擊錨點(diǎn)定位,鼠標(biāo)滾動(dòng)定位
這篇文章主要介紹了Vue中的element tabs點(diǎn)擊錨點(diǎn)定位,鼠標(biāo)滾動(dòng)定位方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
在Vue中使用SQLite數(shù)據(jù)庫的基礎(chǔ)應(yīng)用詳解
這篇文章主要為大家詳細(xì)介紹了在Vue中使用SQLite數(shù)據(jù)庫的基礎(chǔ)應(yīng)用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
vue3前端實(shí)現(xiàn)微信支付詳細(xì)步驟
這篇文章主要給大家介紹了vue3前端實(shí)現(xiàn)微信支付的詳細(xì)步驟,隨著移動(dòng)端的普及和互聯(lián)網(wǎng)購買需求的增加,微信支付在電商領(lǐng)域中發(fā)揮著越來越重要的作用,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2023-11-11
vue.js移動(dòng)端tab組件的封裝實(shí)踐實(shí)例
本篇文章主要介紹了vue.js移動(dòng)端tab的封裝實(shí)踐實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Vue通過axios調(diào)用json地址數(shù)據(jù)的方法
在現(xiàn)代Web開發(fā)中,前后端分離已成為標(biāo)準(zhǔn)做法,Vue.js作為前端框架中的佼佼者,提供了豐富的API來處理數(shù)據(jù)和服務(wù)端的交互,其中一個(gè)常用的庫是axios,本文將詳細(xì)介紹如何在Vue項(xiàng)目中使用axios來調(diào)用JSON數(shù)據(jù),需要的朋友可以參考下2024-09-09
element-plus中el-table點(diǎn)擊單行修改背景色方法
這篇文章主要給大家介紹了關(guān)于element-plus中el-table點(diǎn)擊單行修改背景色的相關(guān)資料,這是產(chǎn)品新加了的一個(gè)需求,分享給同樣遇到這個(gè)需求的朋友,需要的朋友可以參考下2023-07-07
利用Vue3 (一)創(chuàng)建Vue CLI 項(xiàng)目
這篇文章主要介紹利用Vue3 創(chuàng)建Vue CLI 項(xiàng)目,下面文章內(nèi)容附有官方文檔鏈接,安裝過程,需要的可以參考一下2021-10-10
詳解vee-validate的使用個(gè)人小結(jié)
本篇文章主要介紹了詳解vee-validate的使用個(gè)人小結(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-06-06

