vuex筆記

本文基本上是官方教程的盜版,用通俗易懂的文字講解Vuex,也對原文內容有刪減。javascript

若是你對以上聲明不介意,那麼就能夠繼續看本文,但願對你有所幫助。html

學習一個新技術,必需要清楚兩個W,"What && Why"。vue

"XX 是什麼?","爲何要使用 XX ,或者說 XX 有什麼好處",最後纔是"XX 怎麼使用"。java

Vuex是什麼?

Vuex 相似 Redux 的狀態管理器,用來管理Vue的全部組件狀態。vuex

爲何使用Vuex?

當你打算開發大型單頁應用(SPA),會出現多個視圖組件依賴同一個狀態,來自不一樣視圖的行爲須要變動同一個狀態。app

遇到以上狀況時候,你就應該考慮使用Vuex了,它能把組件的共享狀態抽取出來,當作一個全局單例模式進行管理。這樣無論你在何處改變狀態,都會通知使用該狀態的組件作出相應修改。less

下面講解如何使用Vuex。異步

最簡單的Vuex示例

本文就不涉及如何安裝Vuex,直接經過代碼講解。函數

import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } })

以上就是一個最簡單的Vuex,每個Vuex應用就是一個store,在store中包含組件中的共享狀態state和改變狀態的方法(暫且稱做方法)mutations學習

須要注意的是隻能經過mutations改變store的state的狀態,不能經過store.state.count = 5;直接更改,state至關於對外的只讀屬性。

使用store.commit方法觸發mutations改變state:

store.commit('increment');

console.log(store.state.count) // 1

一個簡簡單單的Vuex應用就實現了。

在Vue組件使用Vuex

若是但願Vuex狀態更新,相應的Vue組件也獲得更新,最簡單的方法就是在Vue的computed(計算屬性)獲取state

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

上面的例子是直接操做全局狀態store.state.count,那麼每一個使用該Vuex的組件都要引入。爲了解決這個,Vuex經過store選項,提供了一種機制將狀態從根組件注入到每個子組件中。

// 根組件 import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const app = new Vue({ el: '#app', store, components: { Counter }, template: ` <div class="app"> <counter></counter> </div> ` })

經過這種注入機制,就能在子組件Counter經過this.$store訪問:

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

mapState函數

computed: {
    count () {
        return this.$store.state.count } }

這樣經過count計算屬性獲取同名state.count屬性,是否是顯得過重複了,咱們可使用mapState函數簡化這個過程。

import { mapState } from 'vuex'; export default { computed: mapState ({ count: state => state.count, countAlias: 'count', // 別名 `count` 等價於 state => state.count }) }

還有更簡單的使用方法:

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

Getters對象

若是咱們須要對state對象進行作處理計算,以下:

computed: {
    doneTodosCount () {
        return this.$store.state.todos.filter(todo => todo.done).length } }

若是多個組件都要進行這樣的處理,那麼就要在多個組件中複製該函數。這樣是很沒有效率的事情,當這個處理過程更改了,還有在多個組件中進行一樣的更改,這就更加不易於維護。

Vuex中getters對象,能夠方便咱們在store中作集中的處理。Getters接受state做爲第一個參數:

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) } } })

在Vue中經過store.getters對象調用。

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

Getter也能夠接受其餘getters做爲第二個參數:

getters: {
  doneTodos: state => { return state.todos.filter(todo => todo.done) }, doneTodosCount: (state, getters) => { return getters.doneTodos.length } }

mapGetters輔助函數

mapState相似,都能達到簡化代碼的效果。mapGetters輔助函數僅僅是將store中的getters映射到局部計算屬性:

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

上面也能夠寫做:

computed: mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ])

因此在Vue的computed計算屬性中會存在兩種輔助函數:

import { mapState, mapGetters } form 'vuex'; export default { // ... computed: { mapState({ ... }), mapGetter({ ... }) } }

Mutations

以前也說過了,更改Vuex的store中的狀態的惟一方法就是mutations

每個mutation都有一個事件類型type和一個回調函數handler

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

調用mutation,須要經過store.commit方法調用mutation type

store.commit('increment')

Payload 提交載荷

也能夠向store.commit傳入第二參數,也就是mutation的payload:

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

單單傳入一個n,可能並不能知足咱們的業務須要,這時候咱們能夠選擇傳入一個payload對象:

mutation: {
    increment (state, payload) { state.totalPrice += payload.price + payload.count; } } store.commit({ type: 'increment', price: 10, count: 8 })

mapMutations函數

不例外,mutations也有映射函數mapMutations,幫助咱們簡化代碼,使用mapMutations輔助函數將組件中的methods映射爲store.commit調用。

import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment' // 映射 this.increment() 爲 this.$store.commit('increment') ]), ...mapMutations({ add: 'increment' // 映射 this.add() 爲 this.$store.commit('increment') }) } }

注 Mutations必須是同步函數。

若是咱們須要異步操做,Mutations就不能知足咱們需求了,這時候咱們就須要Actions了。

相關文章
相關標籤/搜索