Vuex 狀態(tài)管理模式冰抢,類似單例

vuex.png

Vuex 使用單一狀態(tài)樹——是的,用一個對象就包含了全部的應用層級狀態(tài)艘狭。至此它便作為一個“唯一數(shù)據(jù)源 (SSOT (opens new window))”而存在挎扰。這也意味著,每個應用將僅僅包含一個 store 實例巢音。

State:儲存數(shù)據(jù)遵倦,類似vue中的data。

vue中讀取state中的值官撼,由于 Vuex 的狀態(tài)存儲是響應式的骇吭,從 store 實例中讀取狀態(tài)最簡單的方法就是在計算屬性 (opens new window)中返回某個狀態(tài):

調(diào)用 Vue.use(Vuex)

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
  }}
}

mapState 輔助函數(shù)

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

// 在單獨構(gòu)建的版本中輔助函數(shù)為 Vuex.mapState
import { 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) {return state.count + this.localCount
    }})
}

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

computed: mapState([// 映射 this.count 為 store.state.count
    'count'
])

mapState 函數(shù)返回的是一個對象顷链。與局部計算屬性混合使用

computed: {
localComputed () {
 /* ... */ 
},// 使用對象展開運算符將此對象混入到外部對象中
...mapState({
      // ...
   })
}

Getter:(可以認為是 store 的計算屬性)目代。就像計算屬性一樣,getter 的返回值會根據(jù)它的依賴被緩存起來嗤练,且只有當它的依賴值發(fā)生了改變才會被重新計算榛了。

Getter 接受 state 作為其第一個參數(shù):

const store = new Vuex.Store({
  state: {
    todos: [
        { id: 1, text: '...', done: true },
        { id: 2, text: '...', done: false }
    ]
  },
  getters: {
      doneTodos: state => {
          return state.todos.filter(todo => todo.done)
      }
  }
})

Getter 也可以接受其他 getter 作為第二個參數(shù):

getters: {
    // ...
    doneTodosCount: (state, getters) => {
        return getters.doneTodos.length
    }
}
store.getters.doneTodosCount // -> 1

我們可以很容易地在任何組件中使用它:

computed: {
    doneTodosCount () {
        return this.$store.getters.doneTodosCount
  }
}

注意,getter 在通過屬性訪問時是作為 Vue 的響應式系統(tǒng)的一部分緩存其中的煞抬。

也可以通過讓 getter 返回一個函數(shù)霜大,來實現(xiàn)給 getter 傳參。在對 store 里的數(shù)組進行查詢時非常有用革答。

getters: {
    // ...
    getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
    }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

注意战坤,getter 在通過方法訪問時,每次都會去進行調(diào)用残拐,而不會緩存結(jié)果途茫。

mapGetters 輔助函數(shù)

mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計算屬性:

import { mapGetters } from 'vuex'
export default {
    // ...
    computed: {
        // 使用對象展開運算符將 getter 混入 computed 對象中
        ...mapGetters([
            'doneTodosCount',
            'anotherGetter',
            // ...
        ])
    }
}

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

...mapGetters({
    // 把 `this.doneCount` 映射為 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})

Mutation

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

Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調(diào)函數(shù) (handler)戴差。這個回調(diào)函數(shù)就是我們實際進行狀態(tài)更改的地方昔字,并且它會接受 state 作為第一個參數(shù):

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {// 變更狀態(tài)
      state.count++
    }
  }
})

不能直接調(diào)用一個 mutation handler悉患。這個選項更像是事件注冊:“當觸發(fā)一個類型為 increment的 mutation 時搬卒,調(diào)用此函數(shù)业扒《3疲”要喚醒一個 mutation handler,你需要以相應的 type 調(diào)用 store.commit 方法:

store.commit('increment')

你可以向 store.commit 傳入額外的參數(shù)笑窜,即 mutation 的 載荷(payload):

// ...
mutations: {increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

在大多數(shù)情況下致燥,載荷應該是一個對象,這樣可以包含多個字段并且記錄的 mutation 會更易讀:

// ...
mutations: {increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {
  amount: 10
})

提交 mutation 的另一種方式是直接使用包含 type 屬性的對象:

store.commit({
  type: 'increment',
  amount: 10
})

當使用對象風格的提交方式排截,整個對象都作為載荷傳給 mutation 函數(shù)嫌蚤,因此 handler 保持不變:

mutations: {increment (state, payload) {
    state.count += payload.amount
  }
}

Mutation 必須是同步函數(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` 也支持載荷:
      'incrementBy' 
      // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
      ]),
    ...mapMutations({
      add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
    })
  }
}

Action:

Action 類似于 mutation脱吱,不同在于:

  • Action 提交的是 mutation,而不是直接變更狀態(tài)认罩。

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

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {increment (state) {
      state.count++
    }
  },
  actions: {increment (context) {
      context.commit('increment')
    }
  }
})

Module:

將 store 分割成模塊(module)。每個模塊擁有自己的 state垦垂、mutation宦搬、action、getter劫拗、甚至是嵌套子模塊——從上至下進行同樣方式的分割:

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)

Vuex官網(wǎng):https://v3.vuex.vuejs.org/zh/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末间校,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子页慷,更是在濱河造成了極大的恐慌憔足,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酒繁,死亡現(xiàn)場離奇詭異滓彰,居然都是意外死亡,警方通過查閱死者的電腦和手機州袒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門揭绑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稳析,你說我怎么就攤上這事洗做」眩” “怎么了彰居?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撰筷。 經(jīng)常有香客問我陈惰,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任抬闯,我火速辦了婚禮井辆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘溶握。我一直安慰自己杯缺,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布睡榆。 她就那樣靜靜地躺著萍肆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胀屿。 梳的紋絲不亂的頭發(fā)上塘揣,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機與錄音宿崭,去河邊找鬼亲铡。 笑死,一個胖子當著我的面吹牛葡兑,可吹牛的內(nèi)容都是我干的奖蔓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼讹堤,長吁一口氣:“原來是場噩夢啊……” “哼锭硼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜕劝,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤檀头,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后岖沛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暑始,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年婴削,在試婚紗的時候發(fā)現(xiàn)自己被綠了廊镜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡唉俗,死狀恐怖嗤朴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虫溜,我是刑警寧澤雹姊,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站衡楞,受9級特大地震影響吱雏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一歧杏、第九天 我趴在偏房一處隱蔽的房頂上張望镰惦。 院中可真熱鬧,春花似錦犬绒、人聲如沸旺入。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眨业。三九已至,卻和暖如春沮协,著一層夾襖步出監(jiān)牢的瞬間龄捡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工慷暂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聘殖,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓行瑞,卻偏偏與公主長得像奸腺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子血久,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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

  • state: 最底層的初始數(shù)據(jù) getters: 相當于vue的計算屬性突照,對state數(shù)據(jù)進行處理 、擴展 mu...
    唯軒_443e閱讀 910評論 0 0
  • Vuex 是什么氧吐? Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式讹蘑。它采用集中式存儲管理應用的所有...
    skycolor閱讀 837評論 0 1
  • 對于學習過react的同學可能比較清楚,在react我們是通過redux來處理狀態(tài)管理的筑舅,那么現(xiàn)在火熱的vue是如...
    我是上帝可愛多閱讀 2,864評論 0 4
  • Vuex 狀態(tài)管理模式 在使用vue開發(fā)過程中座慰,經(jīng)常會遇到一個狀態(tài)在多個組件之間使用,這時候就需要用vuex來狀態(tài)...
    哭泣哭泣帕拉達閱讀 399評論 0 0
  • Vuex是什么翠拣? Vuex是一個專為Vue.js應用程序開發(fā)的狀態(tài)管理模式Vuex是全局的狀態(tài)管理 Vuex用來做...
    gitJason閱讀 290評論 0 1