Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式
。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
例如:你有幾個數據,幾個操作,在多個組件上都需要使用,如果每個組件都去調用都是寫,就會很麻煩,代碼又臭又長。當然 如果沒有大量的操作和數據需要在多個組件內使用的話呢,其實也就可以不用這個 Vuex了。看個人吧!
Vuex的作用類似全局對象,Vuex 使用單一狀態樹,用一個對象State包含了整個應用層級的所有狀態,你可以理解爲這些狀態就是一堆全局變量和數據。
一、註冊store
1、首先爲了項目格式便於維護和相對規範一點,我們先在 目錄下建立一個 store 文件夾,並且在下面建立一個 store.js 文件(有些項目會命名爲index.js)
2、先引入 Vue 和 Vuex ,並且別忘了 Vue.use(Vuex)
在src/main.js文件裏引入store
二、state
1、現在開始 Vuex 的主宰部分 new Vuex.Store({})
在這張圖上可以清楚的看到 new Vuex.Store 裏面有一個 state: { } ,註釋也寫了。
這是你要設置的全局訪問的 state 對象,也就是你需要 count 就丟個 count進去,需要 price 就丟個 price進去。
這裏我丟了個 count 和 ChangeShowCom 兩個不同的數據類型 作爲一個對比。
2、在頁面中獲取 state 裏面的數據
通過 this.$store.state.count 可以拿到 state裏面的 count 也就是0
三、getters
getters 和 組件的 computed 類似,方便直接生成一些可以直接用的數據。當組裝的數據要在多個頁面使用時,就可以使用 getters 來做
註釋也寫了,getters 可以實時監聽state值的變化(最新狀態)
我給getters裏面獲取count值的方法命名爲 getCount 並且需要傳入 state
同理,通過 this.$store.getters.getCount 可以在頁面獲取 count 值。
四、mutations
通過 mutations 修改 store 中的值
我們現在Hello World.vue文件中添加兩個按鈕,一個加1,一個減1;
這裏我們點擊按鈕調用add(執行加的方法)和del(執行減法的方法),然後在裏面直接提交mutations中的方法修改值:
修改store.js文件,添加mutations,在mutations中定義兩個函數,用來對count加1和減1,
這裏定義的兩個方法就是上面commit提交的兩個方法,如下:
我們可以將參數傳遞給 mutations 中的函數進行計算,這裏是 num
現在我們看看效果 :
很好,count 數值都發生了改變,我點擊了兩下,並且是可以在 Vue Devtools 中的 Vuex 看到過程效果
payload :1 就是數值變化1
type : “addCount” 操作的方法是 addCount,也就是 mutations 根方法
五、Actions
Action 類似於 mutation,不同在於:
Action 提交的是 mutation,而不是直接變更狀態。
Action 可以包含任意異步操作。
我們來看一下:
然後我們去修改Hello World.vue文件:
這裏我們把commit提交mutations,修改爲使用dispatch來提交actions
我們點擊頁面,效果是一樣的。
現在讓我們來看看效果,這裏我又點擊了6下,很顯然,效果是一樣的。
六、modules
可以將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割
隨着項目的複雜度增大,爲了方便管理vuex,一般會將其按功能分割成不同的模塊(Module),方便日後管理。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import * as getters from './getters'
import moduleA from './module/moduleA' // 模塊A
import moduleB from './module/moduleB' // 模塊B
Vue.use(Vuex)
export default new Vuex.Store({
actions,
getters,
state,
mutations,
modules: {
moduleA,
moduleB
}
})
moduleA.js / moduleB.js 文件
// 每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊
export default {
state: {
text: 'moduleA'
},
getters: {},
mutations: {},
actions: {}
}
然後我們就在組件裏這麼調用就可以了
<template>
<div class="demo">
<h1>{{getText1}}</h1>
<h1>{{getText2}}</h1>
</div>
</template>
computed: {
getText1(){
return this.$store.state.moduleA.text;
},
//或
...mapState({
getText2: state => state.moduleB.text;
})
}
由此可知,模塊內部的 state 是局部的,只屬於模塊本身所有,所以外部必須通過對應的模塊名進行訪問。
七、輔助函數 mapState、mapGetters、mapActions
1、…mapState、…mapGetters
如果我們不喜歡這種在頁面上使用 this.$stroe.state.count 和 this.$store.dispatch(‘funName’) 這種很長的寫法,
那麼我們可以使用mapState、mapGetters、mapActions就不會這麼麻煩了;
並且我們配合 … 拓展符 一起使用。
正常顯示,效果是一樣的,我們就可以不再使用很長的寫法來調用了。
2、…mapActions
- vuex 中數據是單向流動的,state =》components =》 actions =》mutations =》state
,如果需要傳入參數,需要在組件和用戶交互的時候傳遞,在某個組件的某個事件中(例如:點擊事件) - 參數的流向是一層一層向下的,從 components =》actions =》 mutations =》 state
=》components,和數據的流向一致