如何在Vue項(xiàng)目中使用axios請(qǐng)求
在實(shí)際的項(xiàng)目中,和后臺(tái)的數(shù)據(jù)交互是少不了的,我通常使用的是 axios 庫(kù),所以以下示例也是以 axios 為基礎(chǔ)來(lái)進(jìn)行封裝的。
1、安裝首先是 npm 安裝 axios 很簡(jiǎn)單:npm install axios
2、沒(méi)有封裝存在的問(wèn)題如果在沒(méi)有封裝接口的項(xiàng)目中,在文件中隨處可以看到如下的接口調(diào)用方法:
this.$axios.post('/user/add', { params: {name: this.name,age: this.age }}).then(res => { console.log(res)}).then(err => { console.log(res)})
這樣寫(xiě)不是不可以,但是存在一些缺陷,接口請(qǐng)求的 url 散布在各個(gè)文件中,如果需要在接口調(diào)用成功或失敗時(shí)做一些處理,就需要更改每個(gè)文件。所以把這些接口請(qǐng)求統(tǒng)一集中起來(lái),如果有調(diào)整,直接在集中文件中找到修改就好了,而不用再去查每個(gè)文件。
3、創(chuàng)建文件首先在項(xiàng)目的 src 目錄中,新建文件夾及文件目錄結(jié)構(gòu)如下:
├── src 源碼目錄
│ ├── apis 接口文件目錄
│ │ ├── login.api.js 登錄模塊的接口 api
│ │ └── user.api.js 用戶模塊的接口 api
│ ├── services 請(qǐng)求相關(guān)文件目錄
│ │ ├── address.js 請(qǐng)求地址配置文件
│ │ └── request.js axios封裝,請(qǐng)求攔截、響應(yīng)碼處理等操作
api接口文件模塊的劃分,大可以根據(jù)自己的實(shí)際項(xiàng)目,按業(yè)務(wù)功能或業(yè)務(wù)邏輯或其他形式劃分。
4、請(qǐng)求地址配置一般我們的項(xiàng)目環(huán)境都會(huì)有多個(gè),少的也會(huì)有開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境。正常情況下,在開(kāi)發(fā)環(huán)境下和生產(chǎn)模式下有著不同的 baseURL,所以,我們需要根據(jù)不同的環(huán)境切換不同的 baseURL。
address.js 文件:
// 根據(jù) process.env.NODE_ENV 切換不同的 baseURLconst isPro = process.env.NODE_ENV === ’production’module.exports = { // ’apis’:vue.config.js中proxy設(shè)置的代理 baseURL: isPro ? ’http://192.168.100.120/ceds’ : ’/apis’}5、axios 配置,設(shè)置請(qǐng)求頭及響應(yīng)碼處理
大體思路是通過(guò)封裝一個(gè)request類(lèi),其中包含了get、post等請(qǐng)求方法,這些請(qǐng)求方法又都會(huì)去調(diào)用 request 方法,該方法通過(guò)傳入的不同參數(shù)調(diào)用原始的 axios 請(qǐng)求,然后返回一個(gè) Promise。
request.js 文件:
import axios from ’axios’import Qs from ’qs’import Vue from ’vue’import { getToken } from ’@Utils/session.utils’ // 存儲(chǔ)獲取token文件import address from ’./address’ // 請(qǐng)求地址class Request { constructor () {// 創(chuàng)建axios實(shí)例this._axios = axios.create({ baseURL: address.baseURL, timeout: 1000 * 5, // 請(qǐng)求超時(shí)時(shí)間 headers: {}})// 請(qǐng)求攔截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() // 請(qǐng)求頭統(tǒng)一添加token}config.headers = Object.assign(config.headers, requestHeader)return config }, error => {Promise.reject(error) }) } // 根據(jù)請(qǐng)求方式,判斷參數(shù)是放在query中還是body中。 // 最直觀的區(qū)別,比如GET請(qǐng)求把參數(shù)包含在url中,而POST則通過(guò)request body把參數(shù)放置在body體中,所以在提交時(shí)的參數(shù)形式是有區(qū)別的 // 以下列了四種我一般常用請(qǐng)求方式的參數(shù)形式,大家可以自行調(diào)整 /** * 發(fā)送get請(qǐng)求 * @param {String} url地址 * @param {Object} query 查詢參數(shù) * @return json數(shù)據(jù) */ get (url, query = {}) {return this._request(’get’)(url, { ...query}) } /** * 發(fā)送post請(qǐng)求 * @param {String} url地址 * @param {Object} body 查詢參數(shù) * @return json數(shù)據(jù) */ 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); } 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]’ } /** * 設(shè)置請(qǐng)求頭 * @param {Object} header 請(qǐng)求頭 */ setHeaders (header) {Object.keys(header).forEach(key => { this._axios.defaults.headers[key] = header[key]}) } // 處理請(qǐng)求頭 headers handleHeaders () {const headers = {}headers[’XMIME-TYPE’] = ’3’Headers[’Content-Type’] = ’application/json; charset=UTF-8’return headers } /** * 發(fā)送請(qǐng)求 * @param {String} method 請(qǐng)求方法類(lèi)型 * @param headers * @returns {function(*=, *=):Promise<unknown>} * @private */ _request (method, headers) {this.setHeaders(this.handleHeaders()) // 設(shè)置統(tǒng)一的請(qǐng)求頭if (headers) { this.setHeaders(headers) // 自定義請(qǐng)求頭} return (url, data, timeout) => { const config = {url,method,timeout: timeout || this._axios.defaults.timeout } // 構(gòu)造請(qǐng)求 config // 判斷請(qǐng)求類(lèi)型 get post const paramType = [’get’, ’delete’].indexOf(method) !== -1 ? ’params’ : ’data’ config[paramType] = data //參數(shù)序列化 config.paramsSerializer = params => {return Qs.stringify(params, { arrayFormat: ’repeat’ }); } return new Promise((resolve, reject) => {// 發(fā)送真正的請(qǐng)求,驗(yàn)證權(quán)限,檢查404等statusthis._axios .request(config) .then(response => {if (this.handleSuccessStatus(response.data.code, response.data)) { if (response.headers[’content-type’] !== ’text/plain; charset=urf-8’) { resolve( // 對(duì)響應(yīng)結(jié)果二次包裝 Object.assign( { success: Number(response.data.code) === 200, data: response.data.data, msg: response.data.msg}, response.data )) // 處理返回結(jié)果 } else {resolve(response.data) }} }, response => {// 處理錯(cuò)誤碼 if(response.response) { const statusCode = response.response.status this.handleErrorStatus(statusCode)} else { Vue.prototype.$message.error(response.message)}reject(response) }) .catch(err => {reject(err) })}) }} } // 請(qǐng)求成功,返回錯(cuò)誤碼 // 具體狀態(tài)碼跟后臺(tái)開(kāi)發(fā)人員統(tǒng)一,然后根據(jù)狀態(tài)碼進(jìn)行相應(yīng)提示 // 下面是我在項(xiàng)目中的操作,大家可自行調(diào)整擴(kuò)展 handleSuccessStatus (code, data) {let result = ’’let flag = falseswitch (code) { case ’20007’:result = ’未查找到二次認(rèn)證密碼!’flag = truebreak case ’20008’:result = ’您的二次認(rèn)證密碼還未修改,請(qǐng)先修改!’flag = truebreak case ’20009’:result = ’您還未開(kāi)啟二次認(rèn)證,請(qǐng)聯(lián)系管理員!’flag = truebreak case ’90001’:result = ’請(qǐng)輸入二次認(rèn)證密碼!’flag = truebreak case ’90002’:result = ’無(wú)操作權(quán)限!’flag = truebreak default:break}// 進(jìn)行通知// $message方法是我按需引入的element-ui中的提示組件,你可以替換成自己的提示組件if (result) { Vue.prototype.$message.error(result)}return flag } // 根據(jù)錯(cuò)誤碼獲取錯(cuò)誤提示 handleErrorStatus (statusCode) {let errorMsg = ’’if (statusCode === 500) { errorMsg = ’數(shù)據(jù)請(qǐng)求失敗,請(qǐng)聯(lián)系管理員!’} else if (statusCode === 404) { errorMsg = ’請(qǐng)求地址錯(cuò)誤!’} else if (statusCode === 402) { errorMsg = ’當(dāng)前您沒(méi)有權(quán)限操作該數(shù)據(jù)!’} else { errorMsg = ’請(qǐng)求出錯(cuò)!’}// 進(jìn)行通知Vue.prototype.$message.error(errorMsg) }}export default new Request() 6、使用
我們?cè)诮涌诠芾砦募校ㄟ^(guò)調(diào)用上面封裝的 request 類(lèi),傳入對(duì)應(yīng)的參數(shù)即可。
user.api.js 文件:
import http from ’../services/request’/** * @description 獲取用戶列表 * @param {*} params 請(qǐng)求接口的參數(shù) */// 此處定義的reqUserList方法會(huì)調(diào)用我們封裝的request中的get方法,get方法的第一個(gè)參數(shù)是請(qǐng)求地址,第二參數(shù)是query參數(shù)export const reqUserList = params => http.get(’/user/list’, params)
在調(diào)用的 .vue 文件中,引入該方法并傳入?yún)?shù)即可
import { reqUserList } from ’@Apis/user.api’ // 導(dǎo)入apiexport default { name: ’UserList’, ... ... created() { }, methods: {async getUsers() { // 調(diào)用api接口,并傳入?yún)?shù) const res = await reqUserList({page: 1,size: 10 }) console.log(res) // 獲取的響應(yīng)結(jié)果} }}
如此,就完成了對(duì)接口的封裝及基本使用。
PS:以上這些文件名、文件夾名、方法名、路徑等都是我自己取得,你可以按照自己的代碼風(fēng)格習(xí)慣進(jìn)行調(diào)整。
以上就是如何在Vue項(xiàng)目中使用axios請(qǐng)求的詳細(xì)內(nèi)容,更多關(guān)于Vue項(xiàng)目中使用axios的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. JSP的Cookie在登錄中的使用2. XMLDOM對(duì)象方法:對(duì)象屬性3. 博客日志摘要暨RSS技術(shù)4. ASP常用日期格式化函數(shù) FormatDate()5. JSP之表單提交get和post的區(qū)別詳解及實(shí)例6. 使用XSL將XML文檔中的CDATA注釋輸出為HTML文本7. ASP.NET Core實(shí)現(xiàn)中間件的幾種方式8. XML解析錯(cuò)誤:未組織好 的解決辦法9. SSM框架整合JSP中集成easyui前端ui項(xiàng)目開(kāi)發(fā)示例詳解10. 告別AJAX實(shí)現(xiàn)無(wú)刷新提交表單
