您好,登錄后才能下訂單哦!
這篇“vue怎么使用Vuex狀態管理模式”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue怎么使用Vuex狀態管理模式”文章吧。
單向數據流是vue 中父子組件的核心概念,props 是單向綁定的。當父組件的屬性值發生變化的時候,會傳遞給子組件發生相應的變化,從而形成一個單向下行的綁定,父組件的屬性改變會流向下行子組件中,但是反之,為了防止子組件無意間修改了父組件中的數據而影響到了其他的子組件的狀態,vue 規定了從下往上的數據流是不允許的。當我們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:
a、多個組件依賴于同一狀態。組件之間傳參變得特別繁瑣,并且兄弟組件之間狀態傳遞無能為力。
b、來自不同視圖的行為需要變更同一狀態。 經常會采用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。
我們為什么不把組件的共享狀態抽取出來,以一個全局單例模式管理呢?Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。
使用 Vuex 并不意味著你需要將所有的狀態放入 Vuex。雖然將所有的狀態放到 Vuex 會使狀態變化更顯式和易調試,但也會使代碼變得冗長和不直觀。如果有些狀態嚴格屬于單個組件,最好還是作為組件的局部狀態。應該根據你的應用開發需要進行權衡和確定。
CDN 方式: <script src="...vuex.js"></script> NPM 方式: npm install vuex --save Yarn方式: yarn add vuex 其他方式:項目初始化是引入依賴 無論哪種方式都需要 Vue.use(Vuex)來安裝 Vuex
每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含著你的應用中大部分的狀態 vuex的Vuex 核心 State 、Getters 、Mutation、Action、Module。
Vuex也使用了單一狀態樹來管理應用層級的全部狀態。唯一數據源。
單一狀態樹能夠讓我們最直接的方式找到某個狀態的片段,而且在之后的維護和調試過程中,也可以非常方便的管理和維護。
state存儲狀態類似于組件中data,在組件中訪問狀態經常有兩種方法:分別為
a、通過 this.$store.state.屬性 的方式來訪問狀態,通常寫在computed計算屬性中,當然也可以直接通過插值表達式訪問;
b、借助mapState 輔助函數。
核心代碼如下:
<div id="app"> {{ mycount }}<br> 直接插值表達式訪問 {{ this.$store.state.count }}<br> {{ myinfoAge }}<br> </div> <script> import Vue from 'vue'; import Vuex from 'vuex'; import { mapState } from 'vuex'// 使用輔助函數一定記住引入 const store = new Vuex.Store({ // 存儲狀態數據 state: { count: 0, info:{ name:"xiaoming", age:18 } }, ) new Vue({ el: '#app', store, computed:{ // a、計算屬性方式 mycount(){ return this.$store.state.count }, // b、利用輔助函數賦值給對應變量,頁面可以直接使用該變量 ...mapState({ myinfoAge: (state) => state.info.age, }), // 當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給 mapState 傳一個字符串數組。下面的簡化寫法相當于 info: (state) => state.info, ...mapState(["info"]), } }) </script>
store的一個計算屬性,類比組件的計算屬性,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算,Getter 接受 state 作為其第一個參數,在state中的數據發生改變,計算屬性重新計算
Getters 的狀態存儲相當于組件中計算屬性,訪問方式有三種:
a、通過屬性訪問
b、通過方法訪問
c、通過mapGetters 輔助函數訪問
核心代碼如下:
<div id="app"> {{ myInfoLength }}<br> 直接插值表達式訪問 {{ this.$store.getters.infoLength }}<br> {{ myName }}<br> {{ infoLength }} </div> <script> import Vue from 'vue'; import Vuex from 'vuex'; import { mapGetters } from 'vuex'// 使用輔助函數一定記住引入 const store = new Vuex.Store({ state: { info:[ {name:"name1",age:18}, {name:"name2",age:28} ] }, // 存儲狀態數據 getters: { infoLength: (state) => { return state.info.length; }, getNameByAge: (state) => (age) => { return state.info.find(item => item.age === age).name } }, ) new Vue({ el: '#app', store, computed:{ // a、通過屬性訪問 myInfoLength(){ return this.$store.getters.infoLength } // b、通過方法訪問 myName(){ return this.$store.getters.getNameByAge(18) } // c、mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性 ...mapGetters(["infoLength"]) } }) </script>
前面state和getters兩個核心概念都是為了在store存儲數據和訪問數據的使用,Mutation則提供了對store中數據的修改功能,并且是唯一的更新方式,提交Mutation,Mutation主要包括兩部分:字符串的事件類型(type)和一個回調函數(handler),該回調函數的第一個參數就是state。
在視圖組件中不能直接修改store容器中的狀態,需要先在容器中注冊一個事件函數,當需要更新狀態時候需要提交觸發該事件,同時可以向該事件傳遞參數。這里需要區別與組件內v-model雙向綁定。提交事件方法有一下幾種:
a、普通提交方式
b、對象風格提交
c、借助 mapMutations 輔助函數
其核心代碼如下:
<div id="app"> <button @click="handleAdd">點我加一</button> <button @click="handleAddForNum">點我加加</button> <button @click="handleAddForObj">對象添加</button> <button @click="handleAddMap">對象添加</button> </div> <script> import Vue from 'vue'; import Vuex from 'vuex'; import { mapMutations } from 'vuex'// 使用輔助函數一定記住引入 const store = new Vuex.Store({ state: { count:1 }, mutations:{ // 注冊事件 addCount(state){ state.count ++ }, addCountForNum(state,num){ state.count += num }, addCountForObj(state,payload){ state.count += payload.num }, addMap(state){ state.count ++ } } ) new Vue({ el: '#app', store, methods:{ // a、普通提交方式 handleAdd(){ this.$store.commit('addCount') }, handleAddForNum(){ this.$store.commit('addCountForNum',10) }, // b、對象風格提交 handleAddForObj() { this.$store.commit({ type: "addCountForObj", num: 100 }); }, // c、借助 mapMutations 輔助函數 ...mapMutations(["addMap"]), handleAddMap(){ this.addMap() } } }) </script>
Mutation 需遵守 Vue 的響應規則,Vuex 的 store 中的狀態是響應式的,那么當我們變更狀態時,監視狀態的 Vue 組件也會自動更新。這也意味著 Vuex 中的 mutation 也需要與使用 Vue 一樣遵守一些注意事項:最好提前在你的 store 中初始化好所有所需屬性。當需要在對象上添加新屬性時,你應該使用 Vue.set(obj, 'newProp', 123), 或者以新對象替換老對象。例如,利用對象展開運算符 state.obj = { ...state.obj, newProp: 123 }
注意:Mutation 必須是同步函數。在 mutation 中混合異步調用會導致你的程序很難調試。例如,當你調用了兩個包含異步回調的 mutation 來改變狀態,你怎么知道什么時候回調和哪個先回調呢?
Action類似于Mutation, 但是是用來代替Mutation進行異步操作的.action 用于異步的修改state,它是通過muation間接修改state的。
context是和store對象具有相同方法和屬性的對象.也就是說, 我們可以通過context去進行commit相關的操作, 也可以獲取context.state等.
若需要異步操作來修改state中的狀態,首先需要action來注冊事件,組件視圖在通過dispatch分發方式調用該事件,該事件內部提交mutation中的事件完成改變狀態操作,總之,通過action這個中介來提交mutation中的事件函數.分發事件方法如下:
a、普通提交方式
b、對象風格提交
c、借助 mapActions 輔助函數
核心代碼如下:
<div id="app"> <button @click="handleAdd">點我加一</button> <button @click="handleAddTen">點我加十</button> <button @click="handleAddForObj">對象添加</button> <button @click="handleAddMap">對象添加</button> </div> <script> import Vue from 'vue'; import Vuex from 'vuex'; import { mapMutations,mapActions } from 'vuex'// 使用輔助函數一定記住引入 const store = new Vuex.Store({ state: { count:1 }, // 注冊事件修改state狀態值 mutations:{ addCount(state){ state.count ++ }, addCountForNum(state,num){ state.count += num }, addCountForObj(state,payload){ state.count += payload.num }, addMap(state){ state.count ++ } }, // 注冊事件,提交給 mutation actions:{ addAction(context){ setTimeout(() => { context.commit('addCount') }, 1000) }, addActionForNum(context,num){ setTimeout(() => { context.commit('addCountForNum',num) }, 1000) }, addActionForObj(context,payload){ setTimeout(() => { context.commit('addCountForObj',payload) }, 1000) }, addActionMap(context){ setTimeout(() => { context.commit('addMap') }, 1000) } } ) new Vue({ el: '#app', store, methods:{ // a、普通提交方式 handleAdd(){ this.$store.dispatch('addAction') }, handleAddTen(){ this.$store.dispatch('addActionForNum',10) }, // b、對象風格提交 handleAddForObj(){ this.$store.dispatch({ type: 'addActionForObj', amount: 10 }) } // 借助 mapActions 輔助函數 ...mapActions(["addActionMap"]),// 相當于...mapActions({addActionMap:"addActionMap"}) handleAddMap(){ this.addActionMap() } } })
組合 Action:組合多個 action,以處理更加復雜的異步流程.store.dispatch 可以處理被觸發的 action 的處理函數返回的 Promise,并且 store.dispatch 仍舊返回 Promise。一個 store.dispatch 在不同模塊中可以觸發多個 action 函數。在這種情況下,只有當所有觸發函數完成后,返回的 Promise 才會執行。假設 getData() 和 getOtherData() 返回的是 Promise。
actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) } }
Vuex允許我們將store分割成模塊(Module), 而每個模塊擁有自己的state、mutation、action、getters等
(1)Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。
(2)你不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
以上就是關于“vue怎么使用Vuex狀態管理模式”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。