1. 程式人生 > 程式設計 >如何在Vue專案中使用axios請求

如何在Vue專案中使用axios請求

在實際的專案中,和後臺的資料互動是少不了的,我通常使用的是 axios 庫,所以以下示例也是以 axios 為基礎來進行封裝的。

1、安裝

首先是 npm 安裝 axios 很簡單:npm install axios

2、沒有封裝存在的問題

如果在沒有封裝介面的專案中,在檔案中隨處可以看到如下的介面呼叫方法:

this.$axios.post("/user/add",{
    params: {
        name: this.name,age: this.age
    }
})
.then(res => {
    console.log(res)
})
.then(err => {
    console.log(res)
})

這樣寫不是不可以,但是存在一些缺陷,介面請求的 url 散佈在各個檔案中,如果需要在介面呼叫成功或失敗時做一些處理,就需要更改每個檔案。所以把這些介面請求統一集中起來,如果有調整,直接在集中檔案中找到修改就好了,而不用再去查每個檔案。

3、建立檔案

首先在專案的 src 目錄中,新建資料夾及檔案目錄結構如下:

├── src 原始碼目錄

│ ├── apis 介面檔案目錄

│ │ ├── login.api.js 登入模組的介面 api

│ │ └── user.api.js 使用者模組的介面 api

│ ├── services 請求相關檔案目錄

│ │ ├── address.js 請求地址配置檔案

│ │ └── request.js axios封裝,請求攔截、響應碼處理等操作

api介面檔案模組的劃分,大可以根據自己的實際專案,按業務功能或業務邏輯或其他形式劃分。

4、請求地址配置

一般我們的專案環境都會有多個,少的也會有開發環境和生產環境。正常情況下,在開發環境下和生產模式下有著不同的 baseURL,所以,我們需要根據不同的環境切換不同的 baseURL。

address.js 檔案:

// 根據 process.env.NODE_ENV 切換不同的 baseURL
const isPro = process.env.NODE_ENV === 'production'
​
module.exports = {
    // 'apis':
vue
.config.js中proxy設定的代理 baseURL: isPro ? 'http://192.168.100.120/ceds' : '/apis' }

5、axios 配置,設定請求頭及響應碼處理

大體思路是通過封裝一個request類,其中包含了get、post等請求方法,這些請求方法又都會去呼叫 request 方法,該方法通過傳入的不同引數呼叫原始的 axios 請求,然後返回一個 Promise。

request.js 檔案:

import axios from 'axios'
import Qs from 'qs'
import Vue from 'vue'
import { getToken } from '@Utils/session.utils' // 儲存獲取token檔案
import address from './address' // 請求地址
​
class Request {
    constructor () {
        // 建立axios例項
        this._axios = axios.create({
            baseURL: address.baseURL,timeout: 1000 * 5,// 請求超時時間
            headers: {}
        })
        // 請求攔截
        this._axios.interceptors.request.use(
            config => {
                const requestHeader = {
                    'X-Requested-With': 'XMLHttpRequest','Content-Type': 'application/json; charset=UTF-8','Access-Control-Allow-Origin': '*',token: getToken() // 請求頭統一新增token
                }
                config.headers = Object.assign(config.headers,requestHeader)
                return config
            },error => {
                Promise.reject(error)
            }
        )
    }
     
    // 根據請求方式,判斷引數是放在query中還是body中。
    // 最直觀的區別,比如GET請求把引數包含在url中,而POST則通過request body把引數放置在body體中,所以在提交時的引數形式是有區別的
    // 以下列了四種我一般常用請求方式的引數形式,大家可以自行調整
    /**
      * 傳送get請求
      * @param {String} url地址
      * @param {Object} query 查詢引數
      * @return json資料
      */
    get (url,query = {}) {
        return this._request('get')(url,{
            ...query
        })
    }
    /**
      * 傳送post請求
      * @param {String} url地址
      * @param {Object} body 查詢引數
      * @return json資料
      */
    post(url,body = {},headers) {
        let data;
        if(this.isFormData(body)) {
            data = body
        } else if(Array.isArray(body)) {
            data = body
        } else {
            data = { ...body }
        }
        return this._request('post')(url,headers)(url,data)XOInTCBLa;
    }
    put (url,body = {}) {
        return this._request('put')(url,{
            ...body
        });
    }
    delete(url,body = {}) {
        return this._request('delete')(url,{
            ...body
        });
    }
​
    isFormData = v => {
        return Object.prototype.toString.call(v) === '[object FormData]'
    }
​
​
    /**
      * 設定請求頭
      * @param {Object} header 請求頭
      */
    setHeaders (header) {
        Object.keys(header).forEach(key => {
            this._axios.defaults.headers[key] = header[key]
        })
    }
​
    // 處理請求頭 headers
    handleHeaders () {
        const headers = {}
        headers['XMIME-TYPE'] = '3'
        Headers['Content-Type'] = 'application/json; charset=UTF-8'
        return headers
    }
​
    /**
      * 傳送請求
      * @param {String} method 請求方法型別
      * @param headers
      * @returns {function(*=,*=):Promise<unknown>}
      * @private
      */
    _request (method,headers) {
        this.setHeaders(this.handleHeaders()) // 設定統一的請求頭
        if (headers) {
            this.setHeaders(headers) // 自定義請求頭
        }
         
        return (url,data,timeout) => {
            const config = {
                url,method,timeout: timeout || this._axios.defaults.timeout
            } // 構造請求 config
​
            // 判斷請求型別 get post
            const paramType = ['get','delete'].indexOf(method) !== -1 ? 'params' : 'data'
            config[paramType] = data
            //引數序列化
            config.paramsSerializer = params => {
                return Qs.stringify(params,{ arrayFormat: 'repeat' });
            }
             
            return new Promise((resolve,reject) => {
                // 傳送真正的請求,驗證許可權,檢查404等status
                this._axios
                    .request(config)
                    .then(response => {
                        if (this.handleSuccessStatus(response.data.code,response.data)) {
                            if (response.headers['content-type'] !== 'text/plain; charset=urf-8') {
                            resolve(
  www.cppcns.com                                  // 對響應結果二次包裝
                                    Object.assign(
                                      {
                                           success: Number(response.data.code) === 200,data: response.data.data,msg: response.data.msg
                                        }, response.data
                                    )
                                ) // 處理返回結果
                            } else {
                                resolve(response.data)
                            }
                        }
                    },response => {
                        // 處理錯誤碼
                      if(response.response) {
                            const statusCode = response.response.status
                            this.handleErrorStatus(statusCode)
                        } else {
                           Vue.prototype.$message.error(response.message)
                        }
                        reject(response)
                    })
                    .catch(err => {
                        reject(err)
                    })
                })
            }
        }
    }
​
    // 請求成功,返回錯誤碼
    // 具體狀態碼跟後臺開發人員統一,然後根據狀態碼進行相應提示
    // 下面是我在專案中的操作,大家可自行調整擴充套件
    handleSuccessStatus (code,data程式設計客棧) {
        let result = ''
        let flag = false
        switch (code) {
            case '20007':
                result = '未查詢到二次認證密碼!'
                flag = true
                break
            case '20008':
                result = '您的二次認證密碼還未修改,請先修改!'
                flag = true
                break
            case '20009':
                result = '您還未開啟二次認證,請聯絡管理員!'
                flag = true
                break
            case '90001':
                result = '請輸入二次認證密碼!'
                flag = true
                break
            case '90002':
                result = '無操作許可權!'
                flag = true
                break
            default:
                break
        }
​
        // 進行通知
        // $message方法是我按需引入的element-ui中的提示元件,你可以替換成自己的提示元件
        if (result) {
            Vue.prototype.$message.error(result)
        }
        return flag
    }
    // 根據錯誤碼獲取錯誤提示
    handleErrorStatus (statusCode) {
        let errorMsg = ''
        i程式設計客棧f (statusCode === 500) {
            errorMsg = '資料請求失敗,請聯絡管理員!'
        } else if (statusCode === 404) {
            errorMsg = '請求地址錯誤!'
        } else if (statusCode === 402) {
            errorMsg = '當前您沒有許可權操作該資料!'
        } else {
            errorMsg = '請求出錯!'
        }
        // 進行通知
        Vue.prototype.$message.error(errorMsg)
    }
}
​
export default new Request() 

6、使用

我們在介面管理檔案中,通過呼叫上面封裝的 request 類,傳入對應的引數即可。

user.api.js 檔案:

import http from '../services/request'
​
/**
 * @description 獲取使用者列表
 * @param {*} params 請求介面的引數
 */
// 此處定義的reqUserList方法會呼叫我們封裝的request中的get方法,get方法的第一個引數是請求地址,第二引數是query引數
export const reqUserList = params => http.get('/user/list',params) 

在呼叫的 .vue 檔案中,引入該方法並傳入引數即可

import { reqUserList } from '@Apis/user.api' // 匯入api
​
export default {
    name: 'UserList',http://www.cppcns.com   ... ...
    created() {
     
    },methods: {
        async getUsers() {
            // 呼叫api介面,並傳入引數
            const res = await reqUserList({
                page: 1,size: 10
            })
            console.log(res) // 獲取的響應結果
        }
    }
}

如此,就完成了對介面的封裝及基本使用。

PS:以上這些檔名、資料夾名、方法名、路徑等都是我自己取得,你可以按照自己的程式碼風格習慣進行調整。

以上就是如何在Vue專案中使用axios請求的詳細內容,更多關於Vue專案中使用axios的資料請關注我們其它相關文章!