Vuex理解
vuex是一個專門為vue.js設計的集中式狀態管理架構。狀態?把它理解為在data中的屬性需要共享給其他vue組件使用的部分,就叫做狀態。簡單的說就是data中需要共用的屬性。比如:有幾個頁面要顯示用戶名稱和用戶等級,或者顯示用戶的地理位置。如果不把這些屬性設置為狀態,那每個頁面遇到后,都會到服務器進行查找計算,返回后再顯示。在中大型項目中會有很多共用的數據,所以尤大神給我們提供了vuex。
1.利用npm包管理工具,進行安裝 vuex。在控制命令行中輸入下邊的命令就可以了。
1 | npm install vuex --save |
需要注意的是這里一定要加上 –save,因為你這個包在生產環境中是要使用的。
2.新建一個vuex文件夾(這個不是必須的),并在文件夾下新建store.js文件,文件中引入我們的vue和vuex。
1 2 | import Vue from 'vue'; import Vuex from 'vuex'; |
3.使用vuex,引入之后用Vue.use進行引用。
1 | Vue.use(Vuex); |
實例
1.現在我們store.js文件里增加一個常量對象。store.js文件就是我們在引入vuex時的那個文件。
1 2 3 | const state={ count:1 } |
2.用export default 封裝代碼,讓外部可以引用。
1 2 3 4 | export default new Vuex.Store({ state }) |
3.新建一個vue的模板,位置在components文件夾下,名字叫count.vue。在模板中我們引入我們剛建的store.js文件,并在模板中用{{$store.state.count}}輸出count 的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <template> <div> <h3>{{msg}}</h3> <hr/> <h4>{{$store.state.count}}</h4> </div> </template> <script> import store from '@/vuex/store' export default{ data(){ return{ msg:'Hello Vuex', } }, store } </script> |
4.在store.js文件中加入兩個改變state的方法。
1 2 3 4 5 6 7 8 | const mutations={ add(state){ state.count++; }, reduce(state){ state.count--; } } |
這里的mutations是固定的寫法,意思是改變的,只知道要改變state的數值的方法,必須寫在mutations里就可以了。
5.在count.vue模板中加入兩個按鈕,并調用mutations中的方法。
1 2 3 4 | <div> <button @click="$store.commit('add')">+</button> <button @click="$store.commit('reduce')">-</button> </div> |
State訪問狀態對象
一、通過computed的計算屬性直接賦值
computed屬性可以在輸出前,對data中的值進行改變,利用這種特性把store.js中的state值賦值給模板中的data值。
1 2 3 4 5 | computed:{ count(){ return this.$store.state.count; } } |
這里需要注意的是return this.$store.state.count這一句,一定要寫this,要不會找不到$store的。這種寫法很好理解,但是寫起來是比較麻煩的。
首先要用import引入mapState。
1 | import {mapState} from 'vuex'; |
然后還在computed計算屬性里寫如下代碼:
1 2 3 | computed:mapState({ count:state=>state.count }) |
這里使用ES6的箭頭函數來給count賦值。
1 | computed:mapState(["count"]) |
Mutations修改狀態
Vuex提供了commit方法來修改狀態
1 2 | <button @click="$store.commit('add')">+</button> <button @click="$store.commit('reduce')">-</button> |
store.js文件:
1 2 3 4 5 6 7 8 | const mutations={ add(state){ state.count++; }, reduce(state){ state.count--; } } |
現在store.js文件里給add方法加上一個參數n。添加的地方已經標黃了。
1 2 3 4 5 6 7 8 | const mutations={ add(state,n){ state.count+=n; }, reduce(state){ state.count--; } } |
在Count.vue里修改按鈕的commit( )方法傳遞的參數,我們傳遞10,意思就是每次加10.
1 2 3 4 | <p> <button @click="$store.commit('add',10)">+</button> <button @click="$store.commit('reduce')">-</button> </p> |
這樣兩個簡單的修改就完成了傳值,可以在瀏覽器中實驗一下了。
實際開發中也不喜歡看到$store.commit( )這樣的方法出現,希望跟調用模板里的方法一樣調用。
例如:@click=”reduce” 就和沒引用vuex插件一樣。
要達到這種寫法,只需要簡單的兩部就可以了:
1在模板count.vue里用import 引入我們的mapMutations:
1 | import { mapState,mapMutations } from 'vuex'; |
2在模板的<script>標簽里添加methods屬性,并加入mapMutations
1 2 3 | methods:mapMutations([ 'add','reduce' ]), |
通過上邊兩部,已經可以在模板中直接使用的reduce或者add方法了,就像下面這樣。
1 | <button @click="reduce">-</button> |
getters計算過濾操作
比如現在要對store.js文件中的count進行一個計算屬性的操作,就是在它輸出前,給它加上100.
首先要在store.js里用const聲明我們的getters屬性。
1 2 3 4 5 | const getters = { count:function(state){ return state.count +=100; } } |
寫好了gettters之后,還需要在Vuex.Store()里引入,由于之前已經引入了state盒mutations,所以引入里有三個引入屬性。代碼如下,
1 2 3 | export default new Vuex.Store({ state,mutations,getters }) |
在store.js里的配置算是完成了,需要到模板頁對computed進行配置。在vue 的構造器里邊只能有一個computed屬性,如果你寫多個,只有最后一個computed屬性可用,所以要對上寫的computed屬性進行一個改造。改造時使用ES6中的展開運算符”…”。
1 2 3 4 5 6 | computed:{ ...mapState(["count"]), count(){ return this.$store.getters.count; } }, |
需要注意的是,寫了這個配置后,在每次count 的值發生變化的時候,都會進行加100的操作。
用mapGetters簡化模板寫法:
state和mutations都有map的引用方法把模板中的編碼進行簡化,getters也是有的,來看一下代碼。
首先用import引入mapGetters
1 | import { mapState,mapMutations,mapGetters } from 'vuex'; |
在computed屬性中加入mapGetters
1 | ...mapGetters(["count"]) |
actions異步修改狀態
actions是可以調用Mutations里的方法的,在actions里調用add和reduce兩個方法。
1 2 3 4 5 6 7 8 | const actions ={ addAction(context){ context.commit('add',10) }, reduceAction({commit}){ commit('reduce') } } |
在actions里寫了兩個方法addAction和reduceAction,在方法體里,都用commit調用了Mutations里邊的方法。兩個方法傳遞的參數也不一樣。
· context:上下文對象,這里可以理解稱store本身。
· {commit}:直接把commit對象傳遞過來,可以讓方法體邏輯和代碼更清晰明了。
需要在count.vue模板中編寫代碼,讓actions生效。先復制兩個以前有的按鈕,并改成actions里的方法名,分別是:addAction和reduceAction。
1 2 3 4 | <p> <button @click="addAction">+</button> <button @click="reduceAction">-</button> </p> |
改造一下methods方法,首先還是用擴展運算符把mapMutations和mapActions加入。
1 2 3 4 5 6 | methods:{ ...mapMutations([ 'add','reduce' ]), ...mapActions(['addAction','reduceAction']) }, |
要記得用import把的mapActions引入才可以使用。
現在看的效果和用Mutations作的一模一樣,為了演示actions的異步功能,增加一個計時器(setTimeOut)延遲執行。在addAction里使用setTimeOut進行延遲執行。
1 2 | setTimeOut(()=>{context.commit(reduce)},3000); console.log('我比reduce提前執行'); |
可以看到在控制臺先打印出了‘我比reduce提前執行’這句話
Module模塊組
在vuex/store.js中聲明模塊組,還是用const常量的方法聲明模塊組。代碼如下:
1 2 3 | const moduleA={ state,mutations,getters,actions } |
聲明好后,需要修改原來 Vuex.Stroe里的值:
1 2 3 | export default new Vuex.Store({ modules:{a:moduleA} }) |
現在要在模板中使用count狀態,要用插值的形式寫入。
1 | <h4>{{$store.state.a.count}}</h4> |
如果想用簡單的方法引入,還是要在計算屬性中retrun狀態。寫法如下:
1 2 3 4 5 | computed:{ count(){ return this.$store.state.a.count; } }, |
全部代碼實例
Store代碼:
具體用法demo
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。