解析vue中axios的封裝請求(附步驟碼)
一、簡介
axios 是一個輕量的HTTP客戶端,它基於XMLHttpRequest
服務來執行HTTP 請求,支援豐富的配置,支援Promise,支援瀏覽器端和Node.js 端。自Vue2.0起,尤大大宣布取消對vue-resource
的官方推薦,轉而推薦 axios。現在 axios 已成為大部分 Vue 開發者的首選。 ( 如果你還不熟悉axios,可以在這裡查看它的API。)【相關推薦:vue.js影片教學】
#封裝前,先來看下,不封裝的情況下,一個實際項目中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的
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。
// 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處理前對回應資料進行一輪預先處理。例如過濾回應數據,更多的,是在這裡對各種回應錯誤碼進行統一錯誤處理,還有斷網處理等等。
// 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"> <h1>This is home page</h1> </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的封裝請求(附步驟碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 <router-link to="/"> 組件window.history.back(),方法選擇取決於場景。

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 <script> 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。
