Vuex基本使用的總結--轉載

在 Vue 的單頁面應用中使用,須要使用Vue.use(Vuex)調用插件。
使用很是簡單,只須要將其注入到Vue根實例中。javascript

import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
getter: {
    doneTodos: (state, getters) => {
      return state.todos.filter(todo => todo.done)
    }
  },
  mutations: {
    increment (state, payload) {
      state.count++
    }
  },
actions: {
  addCount(context) {
    // 能夠包含異步操做
    // context 是一個與 store 實例具備相同方法和屬性的 context 對象
  }
}
})
// 注入到根實例
new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App }
})

而後改變狀態:vue

this.$store.commit('increment')

Vuex 主要有四部分:java

  1. state:包含了store中存儲的各個狀態。
  2. getter: 相似於 Vue 中的計算屬性,根據其餘 getter 或 state 計算返回值。
  3. mutation: 一組方法,是改變store中狀態的執行者。
  4. action: 一組方法,其中能夠含有異步操做。

state

Vuex 使用 state來存儲應用中須要共享的狀態。爲了能讓 Vue 組件在 state更改後也隨着更改,須要基於state建立計算屬性。vuex

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

getters

相似於 Vue 中的 計算屬性,能夠在因此來的其餘 state或者 getter改變後自動改變。
每一個getter方法接受 state和其餘getters做爲前兩個參數。數組

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

mutations

前面兩個都是狀態值自己,mutations纔是改變狀態的執行者。mutations用於同步地更改狀態promise

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}

其中,第一個參數是state,後面的其餘參數是發起mutation時傳入的參數。app

this.$store.commit('increment', 10)

commit方法的第一個參數是要發起的mutation名稱,後面的參數均當作額外數據傳入mutation定義的方法中。
規範的發起mutation的方式以下:異步

store.commit({
  type: 'increment',
  amount: 10   //這是額外的參數
})

額外的參數會封裝進一個對象,做爲第二個參數傳入mutation定義的方法中。async

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

actions

想要異步地更改狀態,須要使用actionaction並不直接改變state,而是發起mutation函數

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

發起action的方法形式和發起mutation同樣,只是換了個名字dispatch

// 以對象形式分發
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

action處理異步的正確使用方式

想要使用action處理異步工做很簡單,只須要將異步操做放到action中執行(如上面代碼中的setTimeout)。
要想在異步操做完成後繼續進行相應的流程操做,有兩種方式:

  1. action返回一個 promise
    dispatch方法的本質也就是返回相應的action的執行結果。因此dispatch也返回一個promise
    store.dispatch('actionA').then(() => {
    // ...
    })
    

 2. 利用async/await。代碼更加簡潔。     

// 假設 getData() 和 getOtherData() 返回的是 Promise

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

  

各個功能與 Vue 組件結合

  將stategetter結合進組件須要使用計算屬性: 

computed: {
    count () {
      return this.$store.state.count 
      // 或者 return this.$store.getter.count2
    }
  }

mutationaction結合進組件,須要在methods中調用this.$store.commit()或者this.$store.commit():

methods: {
    changeDate () {
        this.$store.commit('change');
    },
    changeDateAsync () {
        this.$store.commit('changeAsync');
    }
}

爲了簡便起見,Vuex 提供了四個方法用來方便的將這些功能結合進組件。

  1. mapState
  2. mapGetters
  3. mapMutations
  4. mapActions

示例代碼:

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

// ....
computed: {
  localComputed () { /* ... */ },
  ...mapState({
    // 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數
    count(state) {
      return state.count + this.localCount
    }
  }),
  ...mapGetters({
    getterCount(state, getters) {
      return state.count + this.localCount
    }
  })
}
methods: {
  ...mapMutations({
       add: 'increment' // 將 `this.add()` 映射爲`this.$store.commit('increment')`
    }),
  ...mapActions({
      add: 'increment' // 將 `this.add()` 映射爲 `this.$store.dispatch('increment')`
    })
}

若是結合進組件以後不想改變名字,能夠直接使用數組的方式。

methods: {
    ...mapActions([
      'increment', // 將 `this.increment()` 映射爲 `this.$store.dispatch('increment')`

      // `mapActions` 也支持載荷:
      'incrementBy' // 將 `this.incrementBy(amount)` 映射爲 `this.$store.dispatch('incrementBy', amount)`
    ]),
}

將 store分割爲模塊。

能夠將應用的store分割爲小模塊,每一個模塊也都擁有全部的東西:stategettersmutationsactions
首先建立子模塊的文件:

// initial state
const state = {
  added: [],
  checkoutStatus: null
}
// getters
const getters = {
  checkoutStatus: state => state.checkoutStatus
}
// actions
const actions = {
  checkout ({ commit, state }, products) {
  }
}
// mutations
const mutations = {
  mutation1 (state, { id }) {
  }
}
export default {
  state,
  getters,
  actions,
  mutations
}

而後在總模塊中引入:

import Vuex from 'vuex'
import products from './modules/products' //引入子模塊

Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    products   // 添加進模塊中
  }
})

其實還存在命名空間的概念,大型應用會使用。須要時查看文檔便可。Vuex的基本使用大體如此。 

做者:胡不歸vac 連接:https://www.jianshu.com/p/aae7fee46c36 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索