Vuex的五個核心屬性

Vuex的五個核心概念

本文參考自Vue文檔,說的非常詳細屏镊,建議看文檔。

Vuex是什么痰腮?

VueX 是一個專門為 Vue.js 應用設計的狀態(tài)管理架構(gòu)而芥,統(tǒng)一管理和維護各個vue組件的可變化狀態(tài)(你可以理解成 vue 組件里的某些 data )。

Vue有五個核心概念膀值,state,getters,mutations,actions,modules棍丐。本文將對這個五個核心概念進行梳理。

總結(jié)

state => 基本數(shù)據(jù)

getters => 從基本數(shù)據(jù)派生的數(shù)據(jù)

mutations => 提交更改數(shù)據(jù)的方法沧踏,同步歌逢!

actions => 像一個裝飾器,包裹mutations翘狱,使之可以異步秘案。

modules => 模塊化Vuex

State

state即Vuex中的基本數(shù)據(jù)!

單一狀態(tài)樹

Vuex使用單一狀態(tài)樹,即用一個對象就包含了全部的狀態(tài)數(shù)據(jù)阱高。state作為構(gòu)造器選項赚导,定義了所有我們需要的基本狀態(tài)參數(shù)。

在Vue組件中獲得Vuex屬性

我們可以通過Vue的Computed獲得Vuex的state赤惊,如下:

const store =new Vuex.Store({

? ? state: {

? ? ? ? count:0? ? }

})

const app =new Vue({

? ? //..? ? store,

? ? computed: {

? ? ? ? count: function(){

? ? ? ? ? ? returnthis.$store.state.count

? ? ? ? }

? ? },

? ? //..})

每當store.state.count變化的時候, 都會重新求取計算屬性吼旧,并且觸發(fā)更新相關聯(lián)的 DOM。

mapState輔助函數(shù)

當一個組件需要獲取多個狀態(tài)時候未舟,將這些狀態(tài)都聲明為計算屬性會有些重復和冗余圈暗。為了解決這個問題,我們可以使用 mapState 輔助函數(shù)幫助我們生成計算屬性裕膀,讓你少按幾次鍵员串。

// 在單獨構(gòu)建的版本中輔助函數(shù)為 Vuex.mapStateimport { mapState } from 'vuex'export default {

? // ...? computed: mapState({

? ? // 箭頭函數(shù)可使代碼更簡練count: state => state.count,

? ? // 傳字符串參數(shù) 'count' 等同于 `state => state.count`countAlias: 'count',

? ? // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù)? ? countPlusLocalState (state) {

? ? ? returnstate.count +this.localCount

? ? }

? })

}

當映射的計算屬性的名稱與 state 的子節(jié)點名稱相同時魂角,我們也可以給 mapState 傳一個字符串數(shù)組昵济。

computed: mapState([

? // 映射 this.count 為 store.state.count'count'])

對象展開運算符

mapState 函數(shù)返回的是一個對象。我們?nèi)绾螌⑺c局部計算屬性混合使用呢野揪?通常访忿,我們需要使用一個工具函數(shù)將多個對象合并為一個,以使我們可以將最終對象傳給 computed 屬性斯稳。但是自從有了對象展開運算符海铆,我們可以極大地簡化寫法:

computed: {

? localComputed () //本地計算屬性//使用對象展開運算符將此對象混入到外部對象中? ...mapState({

? ? //..? })

}

對象運算符?

...展開運算符(spread operator)允許一個表達式在某處展開。展開運算符在多個參數(shù)(用于函數(shù)調(diào)用)或多個元素(用于數(shù)組字面量)或者多個變量(用于解構(gòu)賦值)的地方可以使用挣惰。

展開運算符不能用在對象當中卧斟,因為目前展開運算符只能在可遍歷對象(iterables)可用。iterables的實現(xiàn)是依靠[Symbol.iterator]函數(shù)憎茂,而目前只有Array,Set,String內(nèi)置[Symbol.iterator]方法珍语,而Object尚未內(nèi)置該方法,因此無法使用展開運算符竖幔。不過ES7草案當中已經(jīng)加入了對象展開運算符特性板乙。

function test(a,b,c) {

? ? ? ? console.log(a);

? ? ? ? console.log(b);

? ? ? ? console.log(c);

? ? }

? ? varargs = [0,1,2];

? ? test(...args);? // 0? 1? 2

ES7草案中的對象展開運算符?

ES6中還不支持對對象的展開運算符,但是ES7中將支持拳氢。對象展開運算符符可以讓我們更快捷地操作對象募逞,如下例子:

let {x,y,...z}={x:1,y:2,a:3,b:4};

? ? x; //1y;//2z;//{a:3,b:4}

組件仍然保有局部狀態(tài)

使用 Vuex 并不意味著你需要將所有的狀態(tài)放入 Vuex。雖然將所有的狀態(tài)放到 Vuex 會使狀態(tài)變化更顯式和易調(diào)試馋评,但也會使代碼變得冗長和不直觀放接。

如果有些狀態(tài)嚴格屬于單個組件,最好還是作為組件的局部狀態(tài)留特。你應該根據(jù)你的應用開發(fā)需要進行權(quán)衡和確定纠脾。

getters

即從store的state中派生出的狀態(tài)玛瘸。

getters接收state作為其第一個參數(shù),接受其他 getters 作為第二個參數(shù)乳乌,如不需要捧韵,第二個參數(shù)可以省略如下例子:

const store =new Vuex.Store({

? ? state: {

? ? ? ? count:0? ? }市咆,

? ? getters: {

? ? ? ? // 單個參數(shù)countDouble:function(state){

? ? ? ? ? ? returnstate.count * 2? ? ? ? },

? ? ? ? // 兩個參數(shù)countDoubleAndDouble:function(state, getters) {

? ? ? ? ? ? returngetters.countDouble * 2? ? ? ? }

? ? }

})

與state一樣汉操,我們也可以通過Vue的Computed獲得Vuex的getters。

const app =new Vue({

? ? //..? ? store,

? ? computed: {

? ? ? ? count: function(){

? ? ? ? ? ? returnthis.$store.state.count

? ? ? ? },

? ? ? ? countDouble: function(){

? ? ? ? ? ? returnthis.$store.getters.countDouble

? ? ? ? },

? ? ? ? countDoubleAndDouble: function(){

? ? ? ? ? ? returnthis.$store.getters.countDoubleAndDouble

? ? ? ? }

? ? },

? ? //..})

mapGetters 輔助函數(shù)

mapGetters 輔助函數(shù)僅僅是將 store 中的 getters 映射到局部計算屬性蒙兰,與state類似

import { mapGetters } from 'vuex'export default {

? // ...? computed: {

? // 使用對象展開運算符將 getters 混入 computed 對象中? ? ...mapGetters([

? ? ? 'countDouble',

? ? ? 'CountDoubleAndDouble',

? ? ? //..? ? ])

? }

}

如果你想將一個 getter 屬性另取一個名字磷瘤,使用對象形式:

mapGetters({

? // 映射 this.double 為 store.getters.countDoubledouble: 'countDouble'})

mutations

提交mutation是更改Vuex中的store中的狀態(tài)的唯一方法。

mutation必須是同步的搜变,如果要異步需要使用action采缚。

每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調(diào)函數(shù) (handler)。這個回調(diào)函數(shù)就是我們實際進行狀態(tài)更改的地方挠他,并且它會接受 state 作為第一個參數(shù)扳抽,提交載荷作為第二個參數(shù)。(提交荷載在大多數(shù)情況下應該是一個對象),提交荷載也可以省略的殖侵。

const store =new Vuex.Store({

? state: {

? ? count: 1? },

? mutations: {

? ? //無提交荷載? ? increment(state) {

? ? ? ? state.count++? ? }

? ? //提交荷載? ? incrementN(state, obj) {

? ? ? state.count += obj.n

? ? }

? }

})

你不能直接調(diào)用一個 mutation handler贸呢。這個選項更像是事件注冊:“當觸發(fā)一個類型為 increment 的 mutation 時,調(diào)用此函數(shù)拢军±阆荩”要喚醒一個 mutation handler,你需要以相應的 type 調(diào)用 store.commit 方法:

//無提交荷載store.commit('increment')//提交荷載store.commit('incrementN', {

? ? n: 100? ? })

對象風格的提交方式

我們也可以使用這樣包含 type 屬性的對象的提交方式茉唉。

store.commit({

? type: 'incrementN',

? n: 10})

Mutations 需遵守 Vue 的響應規(guī)則

最好提前在你的 store 中初始化好所有所需屬性固蛾。

當需要在對象上添加新屬性時,你應該

使用Vue.set(obj, 'newProp', 123), 或者

以新對象替換老對象度陆。例如艾凯,利用對象展開運算符我們可以這樣寫state.obj = {...state.obj, newProp: 123 }

mapMutations 輔助函數(shù)

與其他輔助函數(shù)類似,你可以在組件中使用 this.$store.commit(‘xxx’) 提交 mutation懂傀,或者使用 mapMutations 輔助函數(shù)將組件中的 methods 映射為 store.commit 調(diào)用(需要在根節(jié)點注入 store)趾诗。

import { mapMutations } from 'vuex'export default {

? //..? methods: {

? ? ...mapMutations([

? ? ? 'increment'// 映射 this.increment() 為 this.$store.commit('increment')? ? ]),

? ? ...mapMutations({

? ? ? add: 'increment'// 映射 this.add() 為 this.$store.commit('increment')? ? })

? }

}

actions

Action 類似于 mutation,不同在于:

Action 提交的是 mutation鸿竖,而不是直接變更狀態(tài)沧竟。

Action 可以包含任意異步操作。

我們用如下例子來結(jié)束actions:

const store =new Vuex.Store({

? state: {

? ? count: 0? },

? mutations: {

? ? increment (state) {

? ? ? state.count++? ? }

? },

? actions: {

? ? increment (context) {

? ? ? setInterval(function(){

? ? ? ? context.commit('increment')

? ? ? }, 1000)

? ? }

? }

})

注意:Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象缚忧,因此你可以調(diào)用 context.commit 提交一個 mutation悟泵,或者通過 context.state 和 context.getters 來獲取 state 和 getters。

分發(fā)actions

Action 通過store.dispatch方法觸發(fā):

store.dispatch('increment')

其他與mutations類似的地方

Actions 支持同樣的載荷方式和對象方式進行分發(fā):

// 以載荷形式分發(fā)store.dispatch('incrementN', {

? n: 10})// 以對象形式分發(fā)store.dispatch({

? type: 'incrementN',

? n: 10})

mapActions輔助函數(shù)

你在組件中使用this.$store.dispatch('xxx')分發(fā) action闪水,或者使用mapActions輔助函數(shù)將組件的 methods 映射為store.dispatch調(diào)用(需要先在根節(jié)點注入store):

import { mapActions } from 'vuex'export default {

? //..? methods: {

? ? ...mapActions([

? ? ? 'incrementN'//映射 this.incrementN() 為 this.$store.dispatch('incrementN')? ? ]),

? ? ...mapActions({

? ? ? add: 'incrementN'//映射 this.add() 為 this.$store.dispatch('incrementN')? ? })

? }

}

Modules

使用單一狀態(tài)樹糕非,導致應用的所有狀態(tài)集中到一個很大的對象。但是,當應用變得很大時朽肥,store 對象會變得臃腫不堪禁筏。

為了解決以上問題,Vuex 允許我們將 store 分割到模塊(module)衡招。每個模塊擁有自己的 state篱昔、mutation、action始腾、getters州刽、甚至是嵌套子模塊——從上至下進行類似的分割:

const moduleA = {

? state: { ... },

? mutations: { ... },

? actions: { ... },

? getters: { ... }

}

const moduleB = {

? state: { ... },

? mutations: { ... },

? actions: { ... }

}

const store =new Vuex.Store({

? modules: {

? ? a: moduleA,

? ? b: moduleB

? }

})

store.state.a // -> moduleA 的狀態(tài)store.state.b// -> moduleB 的狀態(tài)

模塊的局部狀態(tài)

對于模塊內(nèi)部的mutation和getter,接收的第一個參數(shù)是模塊的局部狀態(tài),對于模塊內(nèi)部的 getter浪箭,根節(jié)點狀態(tài)會作為第三個參數(shù):

const moduleA = {

? state: { count: 0 },

? mutations: {

? ? increment (state) {

? ? ? // state 模塊的局部狀態(tài)state.count++? ? }

? },

? getters: {

? ? doubleCount (state) {

? ? ? returnstate.count * 2? ? },

? ? sumWithRootCount (state, getters, rootState) {

? ? ? returnstate.count + rootState.count

? ? }

? }

}

同樣穗椅,對于模塊內(nèi)部的 action,context.state是局部狀態(tài)奶栖,根節(jié)點的狀態(tài)是context.rootState:

const moduleA = {

? // ...? actions: {

? ? incrementIfOddOnRootSum (context) {

? ? ? if((context.state.count + context.rootState.count) % 2 === 1) {

? ? ? ? commit('increment')

? ? ? }

? ? }

? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匹表,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宣鄙,更是在濱河造成了極大的恐慌袍镀,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件框冀,死亡現(xiàn)場離奇詭異流椒,居然都是意外死亡,警方通過查閱死者的電腦和手機明也,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門宣虾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人温数,你說我怎么就攤上這事绣硝。” “怎么了撑刺?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵鹉胖,是天一觀的道長。 經(jīng)常有香客問我够傍,道長甫菠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任冕屯,我火速辦了婚禮寂诱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘安聘。我一直安慰自己痰洒,他們只是感情好瓢棒,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丘喻,像睡著了一般脯宿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泉粉,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天连霉,我揣著相機與錄音,去河邊找鬼搀继。 笑死窘面,一個胖子當著我的面吹牛翠语,可吹牛的內(nèi)容都是我干的叽躯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼肌括,長吁一口氣:“原來是場噩夢啊……” “哼点骑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谍夭,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤黑滴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后紧索,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袁辈,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年珠漂,在試婚紗的時候發(fā)現(xiàn)自己被綠了晚缩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡媳危,死狀恐怖荞彼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情待笑,我是刑警寧澤鸣皂,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站暮蹂,受9級特大地震影響寞缝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仰泻,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一荆陆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧我纪,春花似錦慎宾、人聲如沸丐吓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽券犁。三九已至,卻和暖如春汹碱,著一層夾襖步出監(jiān)牢的瞬間粘衬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工咳促, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稚新,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓跪腹,卻偏偏與公主長得像褂删,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子冲茸,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中屯阀,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 2,934評論 0 7
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 730評論 0 3
  • Vuex是什么? Vuex 是一個專為 Vue.js應用程序開發(fā)的狀態(tài)管理模式轴术。它采用集中式存儲管理應用的所有組件...
    蕭玄辭閱讀 3,114評論 0 6
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 343評論 0 0
  • Vuex 的學習記錄 資料參考網(wǎng)址Vuex中文官網(wǎng)Vuex項目結(jié)構(gòu)示例 -- 購物車Vuex 通俗版教程Nuxt....
    流云012閱讀 1,455評論 0 7