vuex詳解

vuex詳解

  yarn add vuexhtml

一、vuex流程圖vue

  vuex能夠幫助咱們管理組件間公共的數據git

  建立一個 store github

// 若是在模塊化構建系統中,請確保在開頭調用了 Vue.use(Vuex)

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

 

  如今,你能夠經過 store.state 來獲取狀態對象,以及經過 store.commit 方法觸發狀態變動:vuex

store.commit('increment')

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

 

 


 

 

二、詳解(state)數組

  

  因爲 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態:緩存

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

  

  每當 store.state.count 變化的時候, 都會從新求取計算屬性,而且觸發更新相關聯的 DOM。app

  這種模式致使組件依賴全局狀態單例ecmascript

  因此,異步

  Vuex 經過 store 選項,提供了一種機制將狀態從根組件「注入」到每個子組件中(需調用 Vue.use(Vuex)):

const app = new Vue({
  el: '#app',
  // 把 store 對象提供給 「store」 選項,這能夠把 store 的實例注入全部的子組件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

  

  經過在根實例中註冊 store 選項,該 store 實例會注入到根組件下的全部子組件中,且子組件能經過 this.$store 訪問到。讓咱們更新下 Counter 的實現:

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

 

  mapState輔助函數

  當一個組件須要獲取多個狀態時候,將這些狀態都聲明爲計算屬性會有些重複和冗餘。

  爲了解決這個問題,咱們可使用 mapState 輔助函數幫助咱們生成計算屬性,讓你少按幾回鍵:

// 在單獨構建的版本中輔助函數爲 Vuex.mapState
import { mapState } from 'vuex'

export default {
  // ...
  computed: mapState({
    // 箭頭函數可以使代碼更簡練
    count: state => state.count,

    // 傳字符串參數 'count' 等同於 `state => state.count`
    countAlias: 'count',

    // 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}

 


 

 

三、詳解(Getter)

  我的理解:至關於獲取計算後的state,將state中某個狀態進行過濾,而後獲取新的狀態

  Vuex 容許咱們在 store 中定義「getter」(能夠認爲是 store 的計算屬性)。

  就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,

  且只有當它的依賴值發生了改變纔會被從新計算。

 

  Getter 接受 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)
    }
  }
})

 

  Getter 會暴露爲 store.getters 對象,你能夠以屬性的形式訪問這些值:

store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

 

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

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

 

  能夠經過讓 getter 返回一個函數,來實現給 getter 傳參。在你對 store 裏的數組進行查詢時很是有用。

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}



store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

  getter 在經過方法訪問時,每次都會去進行調用,而不會緩存結果

 

  mapGetters輔助函數

  僅僅是將 store 中的 getter 映射到局部計算屬性:

import { mapGetters } from 'vuex'

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

 


 

 

四、詳解(Mutation)

  更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation

  Vuex 中的 mutation 很是相似於事件:

  每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。

  這個回調函數就是咱們實際進行狀態更改的地方,

  而且它會接受 state 做爲第一個參數:

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





store.commit('increment')
 

 

  能夠向 store.commit 傳入額外的參數,即 mutation 的 載荷(payload):

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



store.commit('increment', 10)

  mutation 必須是同步函數

  
  你能夠在組件中使用 this.$store.commit('xxx') 提交 mutation,

  或者使用 mapMutations 輔助函數將組件中的 methods 映射爲 

  store.commit 調用(須要在根節點注入 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,而不是直接變動狀態。
    • Action 能夠包含任意異步操做。

 

  咱們能夠在 action 內部執行異步操做:

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

 

  Actions 支持一樣的載荷方式和對象方式進行分發: 

// 以載荷形式分發
store.dispatch('incrementAsync', {
  amount: 10
})

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

 

  在組件中使用 this.$store.dispatch('xxx') 分發 action,

  或者使用 mapActions 輔助函數將組件的 methods 映射爲 

  store.dispatch 調用(須要先在根節點注入 store):

import { mapActions } from 'vuex'

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

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

 

  store.dispatch 能夠處理被觸發的 action 的處理函數返回的 Promise,

  而且 store.dispatch 仍舊返回 Promise:

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

  

  一個action中

store.dispatch('actionA').then(() => {
  // ...
})

 

  另外一個action中

actions: {
  // ...
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

 

  咱們利用 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())
  }
}

 

  一個 store.dispatch 在不一樣模塊中能夠觸發多個 action 函數。

  在這種狀況下,只有當全部觸發函數完成後,返回的 Promise 纔會執行。

 

 
 

 

 

之後再更。

相關文章
相關標籤/搜索