Vue 爬坑之路(六)—— 使用 Vuex + axios 發(fā)送請求
Vue 原本有一個官方推薦的 ajax 插件 vue-resource卸奉,但是自從 Vue 更新到 2.0 之后怎顾,官方就不再更新 vue-resource
目前主流的 Vue 項目溉仑,都選擇 axios 來完成 ajax 請求去枷,而大型項目都會使用 Vuex 來管理數據,所以這篇博客將結合兩者來發(fā)送請求
前言:
Vuex 的安裝將不再贅述闭专,可以參考之前的博客 Vue 爬坑之路(四)—— 與 Vuex 的第一次接觸
使用 cnpm 安裝 axios
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">cnpm install axios -S</pre>
安裝其他插件的時候影钉,可以直接在 main.js 中引入并 Vue.use()平委,但是 axios 并不能 use,只能每個需要發(fā)送請求的組件中即時引入
為了解決這個問題夺谁,有兩種開發(fā)思路廉赔,一是在引入 axios 之后肉微,修改原型鏈,二是結合 Vuex蜡塌,封裝一個 aciton碉纳。具體的實施請往下看~
方案一:改寫原型鏈
首先在 main.js 中引入 axios
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">import axios from 'axios'</pre>
這時候如果在其它的組件中,是無法使用 axios 命令的岗照。但如果將 axios 改寫為 Vue 的原型屬性村象,就能解決這個問題
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">Vue.prototype.$ajax = axios</pre>
在 main.js 中添加了這兩行代碼之后,就能直接在組件的 methods 中使用 $ajax 命令
[](javascript:void(0); "復制代碼")
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">methods: {
submitForm () { this.$ajax({
method: 'post',
url: '/user',
data: {
name: 'wise',
info: 'wrong' }
})
}</pre>
](javascript:void(0); "復制代碼")
****方案二:在 Vuex 中封裝
之前的文章中用到過 Vuex 的 mutations攒至,從結果上看,mutations 類似于事件躁劣,用于提交 Vuex 中的狀態(tài) state
action 和 mutations 也很類似迫吐,主要的區(qū)別在于,action 可以包含異步操作账忘,而且可以通過 action 來提交 mutations
另外還有一個重要的區(qū)別:
mutations 有一個固有參數 state志膀,接收的是 Vuex 中的 state 對象
action 也有一個固有參數 context,但是 context 是 state 的父級鳖擒,包含 state溉浙、getters
Vuex 的倉庫是 store.js,將 axios 引入蒋荚,并在 action 添加新的方法
[](javascript:void(0); "復制代碼")
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">// store.js
import Vue from 'Vue' import Vuex from 'vuex'
// 引入 axios
import axios from 'axios' Vue.use(Vuex)
const store = new Vuex.Store({ // 定義狀態(tài)
state: {
test01: {
name: 'Wise Wrong' },
test02: {
tell: '12312345678' }
},
actions: { // 封裝一個 ajax 方法
saveForm (context) {
axios({
method: 'post',
url: '/user'****,
data: context.state.test02
})
}
}
})
export default store </pre>
[](javascript:void(0); "復制代碼")
注意:即使已經在 main.js 中引入了 axios戳稽,并改寫了原型鏈,也無法在 store.js 中直接使用 $ajax 命令
換言之期升,這兩種方案是相互獨立的
在組件中發(fā)送請求的時候惊奇,需要使用 **this.$store.dispatch **來分發(fā)
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">methods: {
submitForm () {
this.$store.dispatch('saveForm')
}
}</pre>
submitForm 是綁定在組件上的一個方法,將觸發(fā) saveForm播赁,從而通過 axios 向服務器發(fā)送請求
附錄:配置 axios
上面封裝的方法中颂郎,使用了 axios 的三個配置項,實際上只有 url 是必須的容为,完整的 api 可以參考使用說明
為了方便乓序,axios 還為每種方法起了別名,比如上面的 saveForm 方法等價于:
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">axios.post('/user', context.state.test02)</pre>
完整的請求還應當包括 .then 和 .catch
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">.then(function(res){
console.log(res)
})
.catch(function(err){
console.log(err)
})</pre>
當請求成功時坎背,會執(zhí)行 .then替劈,否則執(zhí)行 .catch
這兩個回調函數都有各自獨立的作用域,如果直接在里面訪問 this沼瘫,無法訪問到 Vue 實例
這時只要添加一個 .bind(this) 就能解決這個問題
<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">.then(function(res){
console.log(this.data)
}.bind(****this))</pre>