
首先講講版本問題,如果使用??vue-cli2?
?模版搭建的基礎項目,注意,如果使用??vue?
?版本是2,當你你默認安裝??vuex?
?肯定是??4.x?
?版本了,這里需要注意的是,你要降低??vuex?
?版本到??3.x?
?版本,不然??store?
?掛載不到??vue?
?上
【資料圖】
當我們修改數據,只能通過??mutation?
?修改??state?
?
import Vue from "vue"import Vuex from "vuex"Vue.use(Vuex)export const store = new Vuex.Store({ state: { data: [] }, mutations: { storeData (state, payload) { state.data = state.data.concat(payload) } }})
在頁面中
import { mockFeatchData } from "@/mock"export default { name: "HelloWorld", data () { return { msg: "Welcome to Your Vue.js App" } }, computed: { ...mapState({ dataList: state => state.data }) }, methods: { handleData () { mockFeatchData().then(res => { this.$store.commit("storeData", res) }) } }}
我們修改數據就是??$store.commit("eventName", payload)?
?,當我們觸發??commit?
?時,實際上是已經在異步請求回調里獲取了數據。
但是官方在描述??mutation?
?有這么說,??mutation?
?內部必須是同步函數,異步會導致內部狀態難以追蹤,??devtool?
?難以追蹤??state?
?的狀態
...mutations: { storeData (state, payload) { mockFeatchData().then((res) => { console.log(res) state.data = state.data.concat(res) }) }}
也就是說上面這段代碼,當我們在??mutations?
?中的??storeData?
?中使用了異步函數,我們在??$store.commit("storeData")?
?時,很難追蹤??state?
?的狀態,因為在觸發commit事件時,異步的??回調函數?
?不知道什么時候執行,所以難以追蹤。
??mutations?
?是同步事務,假設在??mutations?
?有多個異步的調用,你很難確定這些異步哪些先執行,很難追蹤??state?
?的變化,所以也給調試帶來了一定難度
??話說回來,這么寫也確實是可以做到更新state的值?
?,如果我不用??vuetool?
?這個工具,貌似也沒毛病
既然??mutations?
??是同步的事情,那么異步官方就使用了??actions?
?方案
??actions?
?里面可以做異步操作,但是并不是直接修改數據,提交的是??mutations?
?里面的方法
mutations: { storeData (state, payload) { state.data = state.data.concat(payload) }},actions: { setStoreData ({ commit }) { mockFeatchData().then((res) => { commit("storeData", res) }) } }
在頁面中就是這樣觸發??actions?
?的
methods: { handleData () { this.$store.dispatch("setStoreData") } }
我們把異步操作放在了??actions?
?的方法里面,你會發現??mockFeatchData?
?這是一個異步操作后的結果,然后通過??commit?
?傳給了??mutations?
?中
在??actions?
?執行異步操作,將結果給了??mutations?
?,??mutations?
?中同步修改狀態??state?
?,使得??actions?
?的操作在??mutations?
?中有記錄。
在??actions?
?中也可以有多個異步操作
mutations: { storeData (state, payload) { state.data = state.data.concat(payload) }, storeText (state, payload) { state.text = payload } }, actions: { setStoreData ({ commit }) { mockFeatchData().then((res) => { console.log(res, "111") commit("storeData", res) }) }, setStoreText ({ dispatch, commit }, payload) { dispatch("setStoreData").then(() => { console.log(222) commit("storeText", payload) }) } }復制代碼
頁面上是這樣觸發??actions?
?的
handleText () { this.$store.dispatch("setStoreText", `hello,${Math.random()}`) }復制代碼
這里我們也可以用對象的方式
handleText () { this.$store.dispatch({ type: "setStoreText", payload: `hello,${Math.random()}`})復制代碼
不過此時注意??actions?
?中獲取值需要解構才行
setStoreText ({ dispatch, commit }, {payload}) { dispatch("setStoreData").then(() => { console.log(222, payload) commit("storeText", payload) })}復制代碼
在actions可以??dispatch?
?另一個異步的操作,也就是等一個任務完成了后,可以執行另一個??commit?
?
看到這里貌似這里有點明白,為啥所有的異步操作放在??actions?
?里面了,??mutation?
?只負責修改??state?
?,所有異步操作產生的副作用的結果都統統交給了??mutation?
?,這樣很好保證??devtool?
?了對數據的追蹤。