[IT 鐵人賽] Vuex 基本入門Day 8 - 工程幼稚園
文章推薦指數: 80 %
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'. 相對應的關係是這樣:. mapState 可以取得 state 裡面的資料。
在我們要聊元件溝通之前,我們先來聊一下關於Vuex這個套件。
他是官方推出的狀態管理的工具,官方中文翻譯叫做倉庫(?),也是啦,如果把store直接翻譯的話,好像叫倉庫也是挺合理的。
但我覺得好像狀態管理會比較符合事實。
Vuex
如果你是使用VueCLI的話,那就是用yarn或npm裝一下就好,
yarnaddvuex
#OR
npmivuex
然後在你的App裡面,你會有幾件事情要做:
Vue.use(Vuex)。
定義你的Store。
把你的VueApp加入Store裡面。
importVuefrom'vue'
importVuexfrom'vuex'
Vue.use(Vuex)
letstore=newVuex.Store({
modules:{
//這邊就放你要的Modules
}
})
exportdefaultstore
我們先回過頭來講講Vuex的基本應用。
Vuex
Vuex在這邊所擔任的角色,是屬於共享狀態管理機制(SharedStateManagement),主要的目的是讓你在各種不同的元件中溝通。
溝通是個簡單的說法,主要的目的還是用於共享某些資訊,用以達到資訊同步的目的。
當然,這個並不是訊息溝通的必要手段。
官方也說,如果不是大型結構的話,你可以自己製作一個狀態儲存機制,並不一定要使用Vuex,畢竟這過於冗餘。
SimpleStateManagementfromScratch
那麼這個狀態管理機制裡面有什麼東西呢?
State狀態儲存的物件,Vuex使用單一狀態樹的方式來存放。
Getters取得狀態資料的方法。
Mutations更新狀態資料的方法。
Actions類似Mutations,但是Actions是呼叫Mutations,且可支援非同步呼叫。
Modules用於分割Vuex的區塊。
有了這寫核心結構概念後,我們來看看新增一個Vuex會有哪些屬性可以使用:
conststore=newVuex.Store({
state:{
age:18
},
mutations:{
incrementAge:function(state){
state.age++
}
},
actions:{
ohMyAge:function(commit){
commit('incrementAge')
}
},
getters:{
getAge:function(state){
returnstate.age
}
}
});
這是一個簡單的Store實例,如果在元件當中,你會有幾個方法,可以從Vuex裡面提出來使用。
import{mapState,mapMutations,mapActions,mapGetters}from'vuex'
相對應的關係是這樣:
mapState可以取得state裡面的資料。
mapMutations可以取得mutations裡面的方法。
mapActions可以取得actions裡面的方法。
mapGetters可以取得getters裡面的方法。
所以說,你們可能會看到這種寫法,
import{mapGetters,mapState}from'vuex'
exportdefault{
name:'MyComponent',
computed:{
...mapGetters([
'getAge'
]),
...mapState([
'age'
])
}
}
這麼你會在template當中可以直接使用{{getAge}},或是你在你的元件裡面,可以使用this.getAge來取得資料。
而如果是mapActions或是mapMutations則是放在methods裡面,
import{mapMutations,mapActions}from'vuex'
exportdefault{
name:'MyComponent',
methods:{
...mapActions([
'ohMyAge'
]),
...mapMutations([
'incrementAge'
])
}
}
這樣你應該知道這些東西相對應在元件或是App裡面可以怎麼使用了。
接著,Vuex還有一些其他的設定:
strict:true啟用嚴謹模式,當你開啟後,你只能透過Mutations來改state的數值,如果直接更改你的state數值,會被警告。
支援插件(Plugin),你可以自己做想要的工具放進去。
在開發模式下,支援熱重載(Hotreloading),這個寫法可以參考官方文件,在開發模式下適用。
最後,剛剛所提到的Modules這個設計,倘若你的結構相當大,那麼為了區分不同的區塊,你可以使用modules來區隔,
consthello={
state:{
//狀態資料
},
mutations:{
//操作方法
}
}
constkitty={
state:{
//狀態資料
},
mutations:{
//操作方法
}
}
conststore=newVuex.Store({
modules:{
hello:hello,
kitty:kitty
}
});
這樣你的Vuex在元件當中,就利用store.state.hello來取得hello的Module當中的資要。
newVue({
computed:{
getHello:function(){
returnstore.state.hello
},
getKitty:function(){
returnstore.state.kitty
}
}
}).$mount('#app')
這裡還有另外一個設定,叫做namespaced。
一般來說,無論是你是否使用Modules,裡面的元件在沒有設定namespaced:true的情況下,mutations,actions,commit,dispatch與getters,大家都是綁訂在全域的料結構內,所以,如果依照剛剛的例子來看:
你會看到在getters裡面有兩個東西,一個叫做getAAge另一個叫做getBAge,如果我們把getAAge這個Module加上namespaced:true之後,他就會變成這樣:
所以說,這樣我們再使用Getters的時候,寫法就會略有差異:
import{mapGetters}from'vuex'
exportdefault{
name:'MyComponent',
computed:{
...mapGetters({
getAAge:'a/getAAge',
getBAge:'getBAge'
})
}
}
這些情況,在mapActions,mapMutations與mapGetters上面都適用。
而,如果你的Module底下還有Module,且也開啟namespaced:true的話,那就可能會有這種結構出現:
import{mapGetters}from'vuex'
exportdefault{
name:'MyComponent',
computed:{
...mapGetters({
getAAge:'a/other/module/getAge'
})
}
}
最後,關於Module這個部分,也可以使用registerModule這個方法來註冊你的Module,例如說:
store.registerModule('myModule',{
//你的Module
})
你也可以註冊巢狀的Module,例如:
store.registerModule(
['myModule','nested'],
{
//你的Module
}
)
另外,Vuex另外也提供了一個方法,叫做createNamespacedHelpers用來取得有命名空間的資料,主要的差異用範例來看比較清楚。
這是原本的寫法,
import{mapGetters}from'vuex'
exportdefault{
name:'MyComponent',
computed:{
...mapGetters({
getAAge:'a/other/module/getAge'
})
}
}
這是使用了createNamespacedHelpers的寫法,
import{createNamespacedHelpers}from'vuex'
import{mapGetters}fromcreateNamespacedHelpers('a/other/module')
exportdefault{
name:'MyComponent',
computed:{
...mapGetters({
getAAge:'getAge'
})
}
}
這樣看得出差異了嗎?當然,這個大前提是,如果你要取得的資訊是在同一組Module裡面,如果你是要跨出其他的Module的話,那麼就不能用這個方式。
關於非同步處理
如果你開啟了嚴謹模式,那麼你要修改資料就只能透過Mutations來做,但是,這個方法不可以使用非同步處理,所以,你必須要透過Actions來處理關於非同步的事情。
那麼,在Actions裡面,我們會有幾個東西可以使用:
conststore=newVuex.Store({
state:{
hello:''
},
mutations:{
setHello:function(state,data){
state.hello=data
}
},
actions:{
setHello:function({commit,dispatch,rootState,state}){
//這邊可以做非同步處理,例如AJAX
axios({
method:'get',
url:'/get/something',
responseType:'json'
}).then(function(res){
commit('setHello',res.data)
});
}
},
getters:{
getHello:function(state){
returnstate.hello
}
}
});
你會看到你可以使用:
commit這個函式是呼叫mutation裡面的方法。
dispatch這個函式是呼叫action裡面的方法。
rootState這個物件是整個Store的state資料。
state這個物件是本地端(Localstate)的資料。
rootGetters這個物件是整個Store的getters資料。
所以,當我們做完axios的非同步傳輸後,可以使用commit或是dispatch來接續後面要做的事情。
而mutation裡面,僅允許同步操作,這樣的非同步操作在mutation裡面是不能使用的。
其他具體的操作可以參考官方說明:
VuexStore
特別提到一點,剛剛的commit與dispatch由於namespaced的設定的關係,所以,他們的第三個參數,可以指定{root:true},表示從Vuex根元件做呼叫一個方法,他可以根據你的Module的設定來戳到你指定的目標。
store.commit('a/other/module',{},{root:true});
store.dispatch('a/other/module',{},{root:true})
這個方法的應用情境,主要是在不同的Module當中,需要去呼叫其他的Module的時候,你必須要加上這個參數,這樣才能觸發到你想要的目標。
不然依照namespaced:true的設定,在你的Module裡面的commit都是觸發你的本地端(Localstate)的方法(包括commit或是dispatch)。
如果你的Module是namespaced:true的話,第三個參數沒有設定,就會被回報錯誤!
所以,當你在Module裡面,且namespaced:true的時候,想要呼叫其他人,就必須指定第三個參數為{root:true}來告訴他,請從根的位置去呼叫。
上述的例子,你會看到我所展開的Store裡面,關於_actions的部分,其中包含了a/setAge與setBAge這兩個方法,這裡其實就是根的位置。
這樣,你應該可以理解第三個參數{root:true}實際上做了什麼事情了。
小結
這裡只是粗略的介紹一下Vuex的功能,實際上使用還是得看你的專案是不是真的需要。
就如同官方說的,小專案用這樣的工具,確實是有點冗餘。
如果你是為了潮,那可以(欸不對)!
vuex的五十道陰影
ITHome鐵人賽同步刊登Vuex基本入門Day8
Home
Twitter
FB
IG
[CSS]Flex/GridLayoutModules,part15
燙傷了手停了幾天,不過差不多15天好像就交代完所有的東西了。
剩下的大部分是比較冷門,甚至是GridLayoutModuleLevel2的事情,雖然支援度還有待商榷,不過還是多少可以講一點。
手是好了點,
[CSS]Flex/GridLayoutModules,part14
中秋連假寫稿好像有點不太應景,所以今天不會講太多東西,最後把Grid單元的對齊稍微補一下,連假嘛,大家輕鬆一點。
不過武漢肺炎肆虐,大家還是小心為上。
單元的對齊如同前些日子提及的,其實就只有兩種,第三種是縮寫不太想把他算進來。
資料的部分就不再次貼過來,忘記的人請參考
[CSS]Flex/GridLayoutModules,part13
單元對齊跟留白的部分今天會繼續,定位的問題基本上不出亂子的話就如同昨天說明的。
當然,如果再加上對齊跟留白,如果不小心也是會爆炸的。
對於留白問題,我一律設定為0(欸不是。
填滿(stretch)與留白(margin)我們現在已經會操作單元軌道來框住
延伸文章資訊
- 1[vuex] module namespace not found in mapActions() - Laracasts
Hello, I would like to add this method to a component: methods: mapActions ('cart', [ 'addProduct...
- 2Mutations | Vuex
- 3[IT 鐵人賽] Vuex 基本入門Day 8 - 工程幼稚園
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'. 相對應的關係是這樣:. mapState 可以取得 ...
- 4Action | Vuex
store.dispatch('xxx') 分发action,或者使用 mapActions 辅助函数将组件的methods 映射为 store.dispatch 调用(需要先在根节点注入 st...
- 5Best practices for Vuex mapping - LogRocket Blog