前面的vuex提到了異步請求,在vue里異步請求怎么請求呢,很顯然jq.ajax是不用了,不是不能用,而是沒必要,jq是操作dom的工具,強行用浪費功能,還會加大打包后的體積,而且是沒有promise的,所以有大佬封裝了新的ajax,名字叫axios,也是vue的作者尤雨溪推薦使用的,這個axios是可以直接在nodejs端使用的
自行百度安裝,axios是沒有封裝成可以讓vue.use()的這種使用模式的,也沒必要,但最好二次封裝下
二次封裝
先去創建一個util的工具文件夾,在里面再新建一個叫request.js文件,直接上代碼
// 引入axios
import axios from 'axios'
import store from 'store'
const service = axios.create({
// url = base url + request url
// 這是請求的前綴的三元運算符,是需要配合proxy使用的
// process.env.NODE_ENV 是nodejs的全局變量,需要懂點nodejs才知道
// 意思是如果是開發【development】環境
// 前綴就是當前本地地址 "localhost:端口" + "/proxy" + "url值"
// 如果不是開發環境,意思就是線上環境,即打包后上線的環境,你讓用戶請求 "localhost:3000" 肯定是請求不到的
// 所以打包出來的就是 "http://xxx.com" + "url值"
baseURL: process.env.NODE_ENV === 'development' ? '/proxy' : 'http://xxx.com', //process.env.VUE_APP_BASE_API
// 最長等待時間
timeout: 5000 // request timeout
})
// 請求前的操作,config參數是請求前的一切數據,可以打印查看
service.interceptors.request.use(
config => {
// 在這里可以做權限的判斷
if(0){
// 不同意請求 return 一個Promise.reject
return Promise.reject("當前賬號無該請求權限")
}
// 從vuex里取token值,如果這么寫上面需要去引入vuex
if (store.getters.token) {
// 可以自動添加請求頭token,就不需要自己手動一次次去寫了
// 什么是token,面試題篇里有
config.headers['X-Token'] = getToken()
}
// 如果同意請求,需要return config
return config
},
error => {
// 錯誤處理
console.log(error) // for debug
return Promise.reject(error)
}
)
// 請求后的操作,response是axios二次封裝的返回值
service.interceptors.response.use(
response => {
// 在返回值可以看到請求的地址
const url = response.config.url;
// 這是真正的返回數據
const res = response.data;
// 可以做一些統一的返回值處理
if (res.code === 2000) {
// 成功就返回res
return res
} else {
return Promise.reject(new Error(res.msg || 'Error'))
}
},
error => {
// 無返回的錯誤處理
return Promise.reject(error)
}
)
// 這就是整個插件了
export default service
如何使用
寫好接口
建議是統一一個文件夾叫req或者叫api,然后根據模塊放置請求

// 引入封裝好的插件
import request from '@/utils/request'
export function getInfo(opt) {
return request({
// 這個在開發環境會變成 "http:localhost:端口" + "/proxy" + "/user/info"
// 正式環境就是 "http:baidu.com" + "/user/info"
url: '/user/info',
method: 'get',
// get用params
params: opt
})
}
export function post(opt) {
return request({
url: '/post',
method: 'post',
// post用data
data: opt
})
}
在vue文件里調用
在vuex使用查看上一篇,跟在vue文件里寫法一樣的
// 引入
import { getInfo,post} from 'api/user';
export default {
data(){
return { ... }
},
mounted(){
getInfo({id:123123}).then(res=>{
console.log(res)
})
},
}
// 因為是promise請求還可以用
Promise.all([getInfo(),post()])
// 或者async
async mounted(){
var res = await getInfo({id:123123})
},
上傳文件
export function upload(formdata) {
return request({
url: '/uploadFile',
method: 'post',
data: formdata,
headers: { 'Content-Type': 'multipart/form-data' },
})
}
注意,axios的post請求是會自動轉成了json字符串【跟文件上傳無關】,如果后端說他不要json格式,一定要key-value的form表單格式,就不能用上面的封裝了,得安裝qs插件,還要修改headers
qs插件
import qs from 'qs';
export function upload(formdata) {
return request({
url: '/form',
method: 'post',
data: qs.stringify(data),
headers: {'content-type': 'application/x-www-form-urlencoded'},
})
}
就上面這么寫,是發不出去請求的
我們上面出現過的這兩句話
1. 這個在開發環境會變成 "http:localhost:端口" + "/proxy" + "/user/info"
2. 正式環境就是 "http:baidu.com" + "/user/info"
在jq-ajax請求的那一篇的最后面就寫過,請求需要滿足的條件
- 需要存在這個請求地址,第一個請求地址一看就沒有,腳手架里怎么會有這個接口呢
- 需要瀏覽器不跨域
如何滿足上面的兩個條件,查看下一篇
補充fetch
fetch並不是一個插件,是跟xhr一樣的,原生的,請求方式,目前兼容不好,普及不多,這里做個記錄
fetch('https://www.baidu.com/search/error.html', {
method: 'POST',
credentials: 'xxx' // 強制加入憑據頭
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式為表單提交
'Accept': 'application/json' // 通過頭指定,獲取的數據類型是JSON
}),
body: new URLSearchParams([["foo", 1],["bar", 2]]).toString()
})
.then((res)=>{
return res.text()
})
.then((res)=>{
console.log(res)
})
