摘要:每一條被記錄,都需要捕捉到前一狀態(tài)和后一狀態(tài)的快照。在組件中提交你可以在組件中使用提交,或者使用輔助函數(shù)將組件中的映射為調(diào)用需要在根節(jié)點(diǎn)注入。當(dāng)模塊被注冊(cè)后,它的所有及都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào)整命名。
vuex中幾個(gè)核心概念: state, getters, mutations, actions, module getters
可以認(rèn)為是store的計(jì)算屬性;與計(jì)算屬性一樣,getter的返回值會(huì)根據(jù)它的依賴(lài)緩存起來(lái),且只有當(dāng)它的依賴(lài)值發(fā)生變化才會(huì)被重新計(jì)算
mapGetters輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性:
import { mapGetters } from "vuex" export default { // ... computed: { // 使用對(duì)象展開(kāi)運(yùn)算符將 getter 混入 computed 對(duì)象中 ...mapGetters([ "doneTodosCount", "anotherGetter", // ... ]) } }mutations 只能是同步操作
更改vuex的store中的狀態(tài)的唯一方法就是提交 mutations
在 mutation 中混合異步調(diào)用會(huì)導(dǎo)致你的程序很難調(diào)試。例如,當(dāng)你能調(diào)用了兩個(gè)包含異步回調(diào)的 mutation 來(lái)改變狀態(tài),你怎么知道什么時(shí)候回調(diào)和哪個(gè)先回調(diào)呢?
mutation必須是同步函數(shù)
mutations: { someMutation (state) { api.callAsyncMethod(() => { state.count++ }) } }
現(xiàn)在想象,我們正在 debug 一個(gè) app 并且觀察 devtool 中的 mutation 日志。每一條 mutation 被記錄,devtools 都需要捕捉到前一狀態(tài)和后一狀態(tài)的快照。然而,在上面的例子中 mutation 中的異步函數(shù)中的回調(diào)讓這不可能完成:因?yàn)楫?dāng) mutation 觸發(fā)的時(shí)候,回調(diào)函數(shù)還沒(méi)有被調(diào)用,devtools 不知道什么時(shí)候回調(diào)函數(shù)實(shí)際上被調(diào)用——實(shí)質(zhì)上任何在回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變都是不可追蹤的。
在組件中提交mutations你可以在組件中使用 this.$store.commit("xxx") 提交 mutation,或者使用 mapMutations 輔助函數(shù)將組件中的 methods 映射為 store.commit 調(diào)用(需要在根節(jié)點(diǎn)注入 store)。
import { mapMutations } from "vuex" export default { // ... methods: { ...mapMutations([ "increment", // 將 `this.increment()` 映射為 `this.$store.commit("increment")` // `mapMutations` 也支持載荷: "incrementBy" // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit("incrementBy", amount)` ]), ...mapMutations({ add: "increment" // 將 `this.add()` 映射為 `this.$store.commit("increment")` }) } }actions 可以是異步操作
action提交的是mutation,而不是直接更改狀態(tài)
action 可以包含任何異步操作
分發(fā) action 在組件中分發(fā)Action你在組件中使用 this.$store.dispatch("xxx") 分發(fā) action,或者使用 mapActions 輔助函數(shù)將組件的 methods 映射為 store.dispatch 調(diào)用(需要先在根節(jié)點(diǎn)注入 store):
import { mapActions } from "vuex" export default { // ... methods: { ...mapActions([ "increment", // 將 `this.increment()` 映射為 `this.$store.dispatch("increment")` // `mapActions` 也支持載荷: "incrementBy" // 將 `this.incrementBy(amount)` 映射為 `this.$store.dispatch("incrementBy", amount)` ]), ...mapActions({ add: "increment" // 將 `this.add()` 映射為 `this.$store.dispatch("increment")` }) } }組合 Action
Action 通常是異步的,那么如何知道 action 什么時(shí)候結(jié)束呢?更重要的是,我們?nèi)绾尾拍芙M合多個(gè) action,以處理更加復(fù)雜的異步流程?
首先,你需要明白 store.dispatch 可以處理被觸發(fā)的 action 的處理函數(shù)返回的 Promise,并且 store.dispatch 仍舊返回 Promise:
// 假設(shè) getData() 和 getOtherData() 返回的是 Promise actions: { async actionA ({ commit }) { commit("gotData", await getData()) }, async actionB ({ dispatch, commit }) { await dispatch("actionA") // 等待 actionA 完成 commit("gotOtherData", await getOtherData()) } }module
由于使用單一狀態(tài)樹(shù),應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象;當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對(duì)象就有可能變得相當(dāng)臃腫。
為了解決以上問(wèn)題,Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割:
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的狀態(tài) store.state.b // -> moduleB 的狀態(tài)
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 會(huì)作為第三和第四參數(shù)傳入 getter,也會(huì)通過(guò) context 對(duì)象的屬性傳入 action。
命名空間默認(rèn)情況下,模塊內(nèi)部的 action、mutation 和 getter 是注冊(cè)在全局命名空間的——這樣使得多個(gè)模塊能夠?qū)ν?mutation 或 action 作出響應(yīng)。
如果希望你的模塊具有更高的封裝度和復(fù)用性,你可以通過(guò)添加 namespaced: true 的方式使其成為命名空間模塊。當(dāng)模塊被注冊(cè)后,它的所有 getter、action 及 mutation 都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào)整命名。例如:
const store = new Vuex.Store({ modules: { account: { namespaced: true, // 模塊內(nèi)容(module assets) state: { ... }, // 模塊內(nèi)的狀態(tài)已經(jīng)是嵌套的了,使用 `namespaced` 屬性不會(huì)對(duì)其產(chǎn)生影響 getters: { isAdmin () { ... } // -> getters["account/isAdmin"] }, actions: { login () { ... } // -> dispatch("account/login") }, mutations: { login () { ... } // -> commit("account/login") }, // 嵌套模塊 modules: { // 繼承父模塊的命名空間 myPage: { state: { ... }, getters: { profile () { ... } // -> getters["account/profile"] } }, // 進(jìn)一步嵌套命名空間 posts: { namespaced: true, state: { ... }, getters: { popular () { ... } // -> getters["account/posts/popular"] } } } } } })
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 會(huì)作為第三和第四參數(shù)傳入 getter,也會(huì)通過(guò) context 對(duì)象的屬性傳入 action。
若需要在全局命名空間內(nèi)分發(fā) action 或提交 mutation,將 { root: true } 作為第三參數(shù)傳給 dispatch 或 commit 即可。
要想使模塊內(nèi)的getter, mutation,action注冊(cè)在模塊命名空間,必須在模塊內(nèi)加上 namespaced: true
使用命名空間在調(diào)用action時(shí)必須使用
this.$store.dispatch("hero1/getHeroInfo"); computed: { doneTodosCount () { return this.$store.getters["hero1/doneTodos"][0].item; } },
參考鏈接
頁(yè)面刷新時(shí),store中的數(shù)據(jù)會(huì)清空解決方案
https://stackoverflow.com/que...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95493.html
摘要:使用構(gòu)建單頁(yè)應(yīng)用新篇在去年的七月六號(hào)的時(shí)候,發(fā)布了一篇使用構(gòu)建單頁(yè)應(yīng)用的文章,文章主要是介紹的基本使用方法,發(fā)現(xiàn)對(duì)大部分的入門(mén)同學(xué)有很大的幫助,時(shí)至今日還有很多同學(xué)不斷的點(diǎn)贊與收藏,瀏覽量最高達(dá)到。 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用【新篇】 在去年的七月六號(hào)的時(shí)候,發(fā)布了一篇 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用 的文章,文章主要是介紹 vuex 的基本使用方法...
摘要:各位看官?zèng)]看過(guò)功能梳理的可以先閱讀下源碼學(xué)習(xí)一功能梳理前車(chē)之鑒有了源碼學(xué)習(xí)的經(jīng)驗(yàn),每次看認(rèn)真鉆研源代碼的時(shí)候都會(huì)抽出一小段時(shí)間來(lái)大體瀏覽一遍源代碼。大體了解這個(gè)源代碼的脈絡(luò),每個(gè)階段做了什么,文件目錄的劃分。 各位看官 沒(méi)看過(guò)功能梳理的可以先閱讀下Vuex源碼學(xué)習(xí)(一)功能梳理. 前車(chē)之鑒 有了vue-router源碼學(xué)習(xí)的經(jīng)驗(yàn),每次看認(rèn)真鉆研源代碼的時(shí)候都會(huì)抽出一小段時(shí)間來(lái)大體瀏覽一...
摘要:最近在研究的相關(guān)知識(shí),最好的學(xué)習(xí)方法莫過(guò)于自己開(kāi)發(fā)一個(gè),這樣帶著問(wèn)題來(lái)學(xué)習(xí),進(jìn)步自然飛速。在首頁(yè)里,我們會(huì)用寫(xiě)一個(gè)導(dǎo)航,通過(guò)的路由導(dǎo)航到不同的應(yīng)用。我們?cè)谖募A里創(chuàng)建一個(gè)新的組件。 最近在研究vue的相關(guān)知識(shí),最好的學(xué)習(xí)方法莫過(guò)于自己開(kāi)發(fā)一個(gè)SPA,這樣帶著問(wèn)題來(lái)學(xué)習(xí),進(jìn)步自然飛速。于是邊查邊寫(xiě)差不多花了2周寫(xiě)完了一個(gè)todo-list,功能不夠完備,但是麻雀雖小,卻也是五臟俱全,基本...
摘要:在之前使用的過(guò)程中,對(duì)于狀態(tài)初始化的設(shè)計(jì)思路,是將其放到一個(gè)全局服務(wù)中,這樣每次進(jìn)到不同頁(yè)面,只需要調(diào)用同一個(gè)全局的動(dòng)作,就能完成初始化。同時(shí),具體的初始化狀態(tài)值,則由每個(gè)模塊自己控制。的中間件有個(gè)特點(diǎn),首先它提供了與動(dòng)作的切入口。 總算把最近嘗試的東西實(shí)現(xiàn)出來(lái)了,寫(xiě)點(diǎn)文章沉淀一下。 前言 單頁(yè)面應(yīng)用在使用單向數(shù)據(jù)流的設(shè)計(jì)方案后,狀態(tài)樹(shù)的控制就變得至關(guān)重要。這里面對(duì)的問(wèn)題在于一個(gè)最基礎(chǔ)...
閱讀 3038·2023-04-25 18:06
閱讀 3307·2021-11-22 09:34
閱讀 2869·2021-08-12 13:30
閱讀 2059·2019-08-30 15:44
閱讀 1671·2019-08-30 13:09
閱讀 1639·2019-08-30 12:45
閱讀 1726·2019-08-29 11:13
閱讀 3617·2019-08-28 17:51