您好,登錄后才能下訂單哦!
這篇“vue中axios的封裝請求怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue中axios的封裝請求怎么實現”文章吧。
axios 是一個輕量的HTTP客戶端,它基于 XMLHttpRequest
服務來執行 HTTP 請求,支持豐富的配置,支持 Promise,支持瀏覽器端和 Node.js 端。自Vue2.0起,尤大大宣布取消對vue-resource
的官方推薦,轉而推薦 axios。現在 axios 已經成為大部分 Vue 開發者的首選。( 如果你還不熟悉 axios,可以在這里查看它的API。)
封裝前,先來看下,不封裝的情況下,一個實際項目中axios請求的樣子。
大概是長這樣:
axios('http://localhost:3000/data', { method: 'GET', timeout: 1000, withCredentials: true, headers: { 'Content-Type': 'application/json', Authorization: 'xxx', }, transformRequest: [function (data, headers) { return data; }], // 其他請求配置... }) .then((data) => { // todo: 真正業務邏輯代碼 console.log(data); }, (err) => { if (err.response.status === 401) { // handle authorization error } if (err.response.status === 403) { // handle server forbidden error } // 其他錯誤處理..... console.log(err); });
可以看到在這段代碼中,頁面代碼邏輯只在第15行處,上方的一大塊請求配置代碼和下方一大塊響應錯誤處理代碼,幾乎跟頁面功能沒有關系,而且每個請求中這些內容都差不多,甚至有的部分完全一樣。
1.封裝步驟
封裝的本質就是在待封裝的內容外面添加各種東西,然后把它們作為一個新的整體呈現給使用者,以達到擴展和易用的目的。
封裝 axios
要做的事情,就是把所有HTTP請求共用的配置,事先都在axios上配置好,預留好必要的參數和接口,然后把它作為新的axios返回。
目錄結構如下(由Vue-cli 3.0 生成):
|--public/
|--mock/
| |--db.json # 我新建的接口模擬數據
|--src/
| |--assets/
| |--components/
| |--router/
| |--store/
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...
2.封裝目標
在 Home 頁,發起 axios 請求時就像調用一個只有少量參數的方法一樣簡單,這樣我就可以專注業務代碼了。
1. 將 axios 封裝到一個獨立的文件
在src下創建 utils/http.js 文件
cd src mkdir utils touch http.js
引入 axios
// src/utils/http.js import axios from 'axios';
創建一個類
//src/utils/http.js //... class NewAxios { }
給不同環境配置不同請求地址
根據process.env.NODE_ENV
配置不同的 baseURL
,使項目只需執行相應打包命令,就可以在不同環境中自動切換請求主機地址。
// src/utils/http.js //... const getBaseUrl = (env) => { let base = { production: '/', development: 'http://localhost:3000', test: 'http://localhost:3001', }[env]; if (!base) { base = '/'; } return base; }; class NewAxios { constructor() { this.baseURL = getBaseUrl(process.env.NODE_ENV); } }
配置超時時間
timeout
屬性,我一般設置10秒。
// src/utils/http.js //... class NewAxios { constructor() { //... this.timeout = 10000; } }
配置允許攜帶憑證
widthCredentials
屬性設為true
// src/utils/http.js //... class NewAxios { constructor() { //... this.withCredentials = true; } }
給這個類創建實例上的方法request
在 request
方法里,創建新的axios實例,接收請求配置參數,處理參數,添加配置,返回axios實例的請求結果(一個promise對象)。
你也可以不創建,直接使用默認導出的axios實例,然后把所有配置都放到它上面,不過這樣一來整個項目就會共用一個axios實例。雖然大部分項目下這樣夠用沒問題,但是有的項目中不同服務地址的請求和響應結構可能完全不同,這個時候共用一個實例就沒辦法支持了。所以為了封裝可以更通用,更具靈活性,我會使用axios
的create
方法,使每次發請求都是新的axios實例。
// src/utils/http.js //... class NewAxios { //... request(options) { // 每次請求都會創建新的axios實例。 const instance = axios.create(); const config = { // 將用戶傳過來的參數與公共配置合并。 ...options, baseURL: this.baseURL, timeout: this.timeout, withCredentials: this.withCredentials, }; // 配置攔截器,支持根據不同url配置不同的攔截器。 this.setInterceptors(instance, options.url); return instance(config); // 返回axios實例的執行結果 } }
因為攔截器配置內容比較多,所以封裝成一個內部函數了。
配置請求攔截器
在發送請求前對請求參數做的所有修改都在這里統一配置。比如統一添加token憑證、統一設置語言、統一設置內容類型、指定數據格式等等。做完后記得返回這個配置,否則整個請求不會進行。
我這里就配置一個token
。
// src/utils/http.js //... class NewAxios { //... // 這里的url可供你針對需要特殊處理的接口路徑設置不同攔截器。 setInterceptors = (instance, url) => { instance.interceptors.request.use((config) => { // 請求攔截器 // 配置token config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || ''; return config; }, err => Promise.reject(err)); } //... }
配置響應攔截器
在請求的then
或catch
處理前對響應數據進行一輪預先處理。比如過濾響應數據,更多的,是在這里對各種響應錯誤碼進行統一錯誤處理,還有斷網處理等等。
我這里就判斷一下403和斷網。
// src/utils/http.js //... class NewAxios { //... setInterceptors = (instance, url) => { //... instance.interceptors.response.use((response) => { // 響應攔截器 // todo: 想根據業務需要,對響應結果預先處理的,都放在這里 console.log(); return response; }, (err) => { if (err.response) { // 響應錯誤碼處理 switch (err.response.status) { case '403': // todo: handler server forbidden error break; // todo: handler other status code default: break; } return Promise.reject(err.response); } if (!window.navigator.online) { // 斷網處理 // todo: jump to offline page return -1; } return Promise.reject(err); }); } //... }
另外,在攔截器里,還適合放置loading等緩沖效果:在請求攔截器里顯示loading,在響應攔截器里移除loading。這樣所有請求就都有了一個統一的loading
效果。
默認導出新的實例
// src/utils/http.js //... export default new NewAxios();
最后完整的代碼如下:
// src/utils/http.js import axios from 'axios'; const getBaseUrl = (env) => { let base = { production: '/', development: 'http://localhost:3000', test: 'http://localhost:3001', }[env]; if (!base) { base = '/'; } return base; }; class NewAxios { constructor() { this.baseURL = getBaseUrl(process.env.NODE_ENV); this.timeout = 10000; this.withCredentials = true; } // 這里的url可供你針對需要特殊處理的接口路徑設置不同攔截器。 setInterceptors = (instance, url) => { instance.interceptors.request.use((config) => { // 在這里添加loading // 配置token config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || ''; return config; }, err => Promise.reject(err)); instance.interceptors.response.use((response) => { // 在這里移除loading // todo: 想根據業務需要,對響應結果預先處理的,都放在這里 return response; }, (err) => { if (err.response) { // 響應錯誤碼處理 switch (err.response.status) { case '403': // todo: handler server forbidden error break; // todo: handler other status code default: break; } return Promise.reject(err.response); } if (!window.navigator.online) { // 斷網處理 // todo: jump to offline page return -1; } return Promise.reject(err); }); } request(options) { // 每次請求都會創建新的axios實例。 const instance = axios.create(); const config = { // 將用戶傳過來的參數與公共配置合并。 ...options, baseURL: this.baseURL, timeout: this.timeout, withCredentials: this.withCredentials, }; // 配置攔截器,支持根據不同url配置不同的攔截器。 this.setInterceptors(instance, options.url); return instance(config); // 返回axios實例的執行結果 } } export default new NewAxios();
現在 axios
封裝算是完成了80%。我們還需要再進一步把axios和接口結合再封裝一層,才能達到我在一開始定的封裝目標。
3. 使用新的 axios 封裝API
在 src 目錄下新建 api 文件夾。把所有涉及HTTP請求的接口統一集中到這個目錄來管理。
新建 home.js
。我們需要把接口根據一定規則分好類,一類接口對應一個js文件。這個分類可以是按頁面來劃分,或者按模塊等等。為了演示更直觀,我這里就按頁面來劃分了。實際根據自己的需求來定。
使用新的 axios 封裝API(固定url的值,合并用戶傳過來的參數),然后命名導出這些函數。
// src/api/home.js import axios from '@/utils/http'; export const fetchData = options => axios.request({ ...options, url: '/data', }); export default {};
在 api 目錄下新建 index.js,把其他文件的接口都在這個文件里匯總導出。
// src/api/index.js export * from './home';
這層封裝將我們的新的axios封裝到了更簡潔更語義化的接口方法中。
現在我們的目錄結構長這樣:
|--public/
|--mock/
| |--db.json # 接口模擬數據
|--src/
| |--api/ # 所有的接口都集中在這個目錄下
| |--home.js # Home頁面里涉及到的接口封裝在這里
| |--index.js # 項目中所有接口調用的入口
| |--assets/
| |--components/
| |--router/
| |--store/
| |--utils/
| |--http.js # axios封裝在這里
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...
4.使用封裝后的axios
現在我們要發HTTP請求時,只需引入 api 下的 index.js 文件就可以調用任何接口了,并且用的是封裝后的 axios。
// src/views/Home.vue <template> <div class="home"> <h2>This is home page</h2> </div> </template> <script> // @ is an alias to /src import { fetchData } from '@/api/index'; export default { name: 'home', mounted() { fetchData() // axios請求在這里 .then((data) => { console.log(data); }) .catch((err) => { console.log(err); }); }, }; </script>
axios請求被封裝在fetchData函數里,頁面請求壓根不需要出現任何axios API,悄無聲息地發起請求獲取響應,就像在調用一個簡單的 Promise 函數一樣輕松。并且在頁面中只需專注處理業務功能,不用被其他事物干擾。
以上就是關于“vue中axios的封裝請求怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。