溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用vue封裝axios請求

發布時間:2022-05-06 14:15:09 來源:億速云 閱讀:230 作者:iii 欄目:大數據
# 如何用Vue封裝Axios請求

## 前言

在現代前端開發中,網絡請求是必不可少的部分。Axios作為當前最流行的HTTP客戶端之一,以其簡潔的API和強大的功能被廣泛使用。而在Vue項目中,合理地封裝Axios不僅能提高代碼復用性,還能統一管理請求邏輯。本文將詳細介紹如何在Vue項目中優雅地封裝Axios請求。

## 一、為什么需要封裝Axios

### 1.1 原始Axios使用的痛點
直接使用Axios雖然簡單,但在實際項目中會面臨:
- 每個請求都需要重復配置基礎URL、headers等
- 缺乏統一的錯誤處理機制
- 難以集中管理API接口
- 不方便添加全局loading狀態
- 難以實現請求取消等功能

### 1.2 封裝帶來的優勢
通過封裝可以實現:
- **統一配置**:基礎路徑、超時時間等
- **攔截器管理**:請求/響應攔截處理
- **API集中管理**:所有接口統一維護
- **更好的擴展性**:便于添加新功能

## 二、基礎封裝實現

### 2.1 創建axios實例

首先在項目中創建`src/utils/request.js`文件:

```javascript
import axios from 'axios'

// 創建axios實例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // 從環境變量獲取基礎URL
  timeout: 10000 // 請求超時時間
})

2.2 添加請求攔截器

// 請求攔截器
service.interceptors.request.use(
  config => {
    // 在發送請求前可以做些什么
    // 例如:添加token
    const token = localStorage.getItem('token')
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    return config
  },
  error => {
    // 對請求錯誤做些什么
    return Promise.reject(error)
  }
)

2.3 添加響應攔截器

// 響應攔截器
service.interceptors.response.use(
  response => {
    // 對響應數據做點什么
    const res = response.data
    
    // 假設后端返回的數據格式為 { code: 200, data: {}, message: '' }
    if (res.code !== 200) {
      // 處理業務錯誤
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res.data
    }
  },
  error => {
    // 對響應錯誤做點什么
    if (error.response) {
      // 處理HTTP狀態碼錯誤
      switch (error.response.status) {
        case 401:
          // 跳轉到登錄頁
          break
        case 403:
          // 提示權限不足
          break
        case 404:
          // 資源不存在
          break
        case 500:
          // 服務器錯誤
          break
      }
    }
    return Promise.reject(error)
  }
)

2.4 導出封裝后的方法

export default service

三、高級封裝技巧

3.1 API模塊化管理

創建src/api目錄,按模塊劃分API:

// src/api/user.js
import request from '@/utils/request'

export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  })
}

export function getUserInfo() {
  return request({
    url: '/user/info',
    method: 'get'
  })
}

3.2 添加全局loading控制

在請求攔截器中:

let loadingInstance

service.interceptors.request.use(config => {
  loadingInstance = Loading.service({
    lock: true,
    text: '加載中...',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  return config
})

service.interceptors.response.use(
  response => {
    loadingInstance.close()
    return response
  },
  error => {
    loadingInstance.close()
    return Promise.reject(error)
  }
)

3.3 請求取消功能

const pendingMap = new Map()

const getPendingKey = (config) => {
  return [config.method, config.url].join('&')
}

service.interceptors.request.use(config => {
  const key = getPendingKey(config)
  if (pendingMap.has(key)) {
    const cancel = pendingMap.get(key)
    cancel()
    pendingMap.delete(key)
  }
  config.cancelToken = new axios.CancelToken(cancel => {
    pendingMap.set(key, cancel)
  })
  return config
})

service.interceptors.response.use(response => {
  const key = getPendingKey(response.config)
  pendingMap.delete(key)
  return response
})

3.4 重試機制

const retryDelay = 1000 // 重試延遲
const retryCount = 3 // 最大重試次數

service.interceptors.response.use(undefined, error => {
  const config = error.config
  if (!config || !config.retry) return Promise.reject(error)
  
  config.__retryCount = config.__retryCount || 0
  if (config.__retryCount >= retryCount) {
    return Promise.reject(error)
  }
  
  config.__retryCount += 1
  return new Promise(resolve => {
    setTimeout(() => resolve(service(config)), retryDelay)
  })
})

四、在Vue組件中使用

4.1 基本使用

import { login } from '@/api/user'

export default {
  methods: {
    async handleLogin() {
      try {
        const res = await login({
          username: 'admin',
          password: '123456'
        })
        console.log('登錄成功', res)
      } catch (error) {
        console.error('登錄失敗', error)
      }
    }
  }
}

4.2 結合Vuex使用

// store/modules/user.js
import { login, getUserInfo } from '@/api/user'

const actions = {
  login({ commit }, userInfo) {
    return new Promise((resolve, reject) => {
      login(userInfo).then(res => {
        commit('SET_TOKEN', res.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  }
}

五、最佳實踐建議

  1. 環境區分:開發、測試、生產環境使用不同的baseURL
  2. 類型提示:為API添加TypeScript類型定義
  3. Mock數據:開發階段使用Mock.js模擬數據
  4. 文檔維護:使用Swagger或YAPI等工具維護API文檔
  5. 性能優化:合理設置緩存策略

六、完整代碼示例

完整的封裝示例可以參考以下結構:

src/
├── api/
│   ├── user.js
│   ├── product.js
│   └── ...
├── utils/
│   ├── request.js
│   └── ...

結語

通過合理的封裝,我們可以將Axios的強大功能與Vue的響應式特性完美結合,構建出健壯、易維護的網絡請求層。本文介紹的方法只是基礎實現,實際項目中可以根據需求進一步擴展和完善。希望本文能幫助你更好地組織Vue項目中的網絡請求代碼。 “`

這篇文章總計約1900字,涵蓋了從基礎封裝到高級技巧的完整內容,采用Markdown格式編寫,包含代碼塊、標題層級和列表等標準Markdown元素。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女