[IT 鐵人賽] Vuex 基本入門Day 8 - 工程幼稚園

文章推薦指數: 80 %
投票人數:10人

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)我們現在已經會操作單元軌道來框住



請為這篇文章評分?