Vuex ~ 專門為vue.js設計的集中式狀態管理架構
阿新 • • 發佈:2018-03-19
state 原來 管理工具 t對象 包管理工具 emp UC maps fault 狀態:data中的屬性需要共享給其他vue組件使用的部分(即data中需要共用的屬性)
1、初識vuex直接來個小demo
下面操作都是基於vue-cli,如果不了解先學習下vue-cli
利用npm包管理工具,進行安裝 vuex。
npm install vuex --save
新建一個vuex文件夾(這個不是必須的),並在文件夾下新建store.js文件,文件中引入我們的vue和vuex。
import Vue from ‘vue‘;
import Vuex from ‘vuex‘;
使用我們vuex,引入之後用Vue.use進行引用。
Vue.use(Vuex);
通過以上操作,vuex就算引用成功了
直接來個demo,在vue-cli的src目錄下新建一個文件夾vuex,並在此文件夾下新建一個store.js文件;直接上demo
2.state訪問狀態對象
現在我們store.js文件裏增加一個常量對象 const state={ count:1 } 用export default 封裝代碼,讓外部可以引用。 export default new Vuex.Store({ state }) 新建一個vue的模板,xxx.vue。在模板中我們引入我們剛建的store.js文件, 並在模板中用{{$store.state.count}}輸出count 的值。 <template> <div> <h2>{{msg}}</h2> <hr/> <h3>{{$store.state.count}}</h3> </div> </template> <script> import store from ‘@/vuex/store‘ export default{ data(){ return{ msg:‘Hello Vuex‘ } }, store //註意要先引用下 } </script> 在store.js文件中加入兩個改變state的方法。 const mutations={ //改變state的數值 add(state){ state.count++; }, reduce(state){ state.count--; } } export default new Vuex.Store({ state, mutations }) 在xxx.vue模板中加入兩個按鈕,並調用mutations中的方法 <div> <button @click="$store.commit(‘add‘)">+</button> <button @click="$store.commit(‘reduce‘)">-</button> </div> 這樣進行預覽就可以實現對vuex中的count進行加減了
上面例子中 const state ,就是訪問狀態對象,也就是兄弟組件間的共享值。 下面是狀態對象賦值給內部對象,也就是把stroe.js中的值,賦值給我們模板裏data中的值 三種賦值方式: 一、通過computed的計算屬性直接賦值 computed:{ count(){ return this.$store.state.count; } } 模板調用:{{count}} 缺點:當一個組件需要獲取多個狀態時候,將這些狀態都聲明為計算屬性會有些重復和冗余。 二、通過mapState的《對象》來賦值 import {mapState} from ‘vuex‘; 然後還在computed計算屬性裏寫如下代碼: computed:mapState({ count:state=>state.count }) 三、通過mapState的《數組》來賦值 computed:mapState(["count"])
3.Mutations修改state狀態
1. mutations 相當於一個對象,對象裏面放的是事件類型相對應的回調函數,作用就是進行狀態更改;簡單理解就相當於一個事件註冊 2. $store.commit() //模板中調用mutations 裏面的事件函數 傳值:只需要在Mutations裏再加上一個參數,並在commit的時候傳遞就就可以了 const mutations={ add(state,n){ state.count+=n; }, reduce(state){ state.count--; } } 在XXX.vue裏修改按鈕的commit( )方法傳遞的參數,我們傳遞10,意思就是每次加10. <p> <button @click="$store.commit(‘add‘,10)">+</button> <button @click="$store.commit(‘reduce‘)">-</button> </p> 模板獲取Mutations方法 實際開發中我們也不喜歡看到$store.commit( )這樣的方法出現,我們希望跟調用模板裏的方法一樣調用。 例如:@click=”reduce” 就和沒引用vuex插件一樣。 要達到這種寫法,只需要簡單的兩部就可以了: 在模板XXX.vue裏用import 引入我們的mapMutations: 1.在模板XXX.vue裏用import 引入我們的mapMutations: import { mapState,mapMutations } from ‘vuex‘; 2.在模板的script標簽裏添加methods屬性,並加入mapMutations methods:mapMutations([ ‘add‘,‘reduce‘ ]), 3.通過上面兩步後調用(註意額外參數直接寫上) <button @click="add(10)">+</button>
4.getters計算過濾操作
getters從表面是獲得的意思,可以把他看作在《 獲取數據之前 》進行的一種再編輯(註意模板顯示getters操作後的值) 相當於對數據的一個過濾和加工,可以把它看作store.js的計算屬性(類似於computed) getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算 《1》基本用法: 首先要在store.js裏用const聲明我們的getters屬性。 const getters = { count:function(state,getters){ return state.count +=getters.params_getter; }, params_getter:function(){ return 1000 } } 參數: state : getters : getters.xxx 來傳遞其他 getters 中的數據 寫好了gettters之後,我們還需要在Vuex.Store()裏引入 export default new Vuex.Store({ state,mutations,getters }) 在store.js裏的配置算是完成了,我們需要到模板頁對computed進行配置 在vue 的構造器裏邊只能有一個computed屬性,如果你寫多個,只有最後一個computed屬性可用, 所以要對computed屬性進行一個改造。 改造時我們使用ES6中的展開運算符”…”。 computed:{ ...mapState(["count"]), //相當於一個擴展 count(){ return this.$store.getters.count; } } 《2》用mapGetters簡化模板寫法: 都知道state和mutations都有map的引用方法把我們模板中的編碼進行簡化,我們的getters也是有的 首先用import引入我們的mapGetters import { mapState,mapMutations,mapGetters } from ‘vuex‘; 在computed屬性中加入mapGetters ...mapGetters(["count"])
5.actions異步修改狀態
actions和之前講的Mutations功能基本一樣 不同點是, 1.actions 提交的是 mutation,而不是直接變更狀態。 2.actions是異步的改變state狀態,而Mutations是同步改變狀態。 在store.js中聲明actions actions是可以調用Mutations裏的方法的,在actions裏調用add和reduce兩個方法 以下是事件註冊的兩種方式: const actions ={ addAction(context){ context.commit(‘add‘,10) }, reduceAction({commit}){ //由於context 與 store 實例具有相同方法和屬性,所以可以提交mutation commit(‘reduce‘) } } 在actions裏寫了兩個方法addAction和reduceAction,在方法體裏,我們都用commit調用了Mutations裏邊的方法。 context:上下文對象,這裏你可以理解稱store實例本身。 {commit}:直接把commit對象傳遞過來,可以讓方法體邏輯和代碼更清晰明了。 模板中的使用 <p> <button @click="addAction">+</button> <button @click="reduceAction">-</button> </p> 改造一下我們的methods方法,首先還是用擴展運算符把mapMutations和mapActions加入 methods:{ ...mapMutations([ ‘add‘,‘reduce‘ ]), ...mapActions([‘addAction‘,‘reduceAction‘]) } 用import把我們的mapActions引入才可以使用 import { mapState,mapMutations,mapGetters,mapActions } from ‘vuex‘; 增加異步檢驗 演示actions的異步功能,我們增加一個計時器(setTimeOut)延遲執行 setTimeOut(()=>{context.commit(reduce)},3000); console.log(‘我比reduce提前執行‘);
6.module模塊組(狀態管理器的模塊組操作)
隨著項目的復雜性增加,我們共享的狀態越來越多,這時候我們就需要把我們狀態的各種操作進行一個分組,分組後再進行按組編寫。 聲明模塊組: 在vuex/store.js中聲明模塊組,我們還是用我們的const常量的方法聲明模塊組。代碼如下: const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } 聲明好後,我們需要修改原來 Vuex.Stroe裏的值: const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的狀態 store.state.b // -> moduleB 的狀態 在模板中使用: 現在我們要在模板中使用count狀態,要用插值的形式寫入 <h3>{{$store.state.a.count}}</h3> 如果想用簡單的方法引入,還是要在我們的計算屬性中rutrun我們的狀態。寫法如下: computed:{ count(){ return this.$store.state.a.count; } }
Vuex ~ 專門為vue.js設計的集中式狀態管理架構