[TOC]
# ***vuex***
> 一個vue的狀態管理器,類似于一個全局變量/方法存儲器,卻能做到更多的事情
一個vuex狀態管理器一般會有三個部分組成,`state` , `mutation` , `action` ,甚至在不需要異步執行代碼的情況下,你可以只使用 `state` 與 `mutation` 進行狀態管理。但實際應用中你可能還會需要 `getter` 與 `module` 方便獲取 `state` 與明化業務分工
## state
問: 什么時候需要用到 store 的 state
答: 雖然可以將所有的狀態放入vuex,但這會讓代碼變得冗長和不直觀。所以vuex中存放的狀態應該為在應用中需要關聯使用的狀態。如果有些狀態嚴格屬于單個組件,最好還是將其作為組件的局部狀態。
### mapState 輔助函數
應用場景: 當一個組件需要獲取多個狀態的時候
~~~
<template>
<div>
? count: {{ count }}
? token: {{ token }}
? countAlias: {{ countA }}
? countFuc: {{ countFuc }}
?</div>
</template>
~~~
~~~
import { mapState } from 'vuex'
?
export default {
?// ...
?data() {
? ?return {
? ? ?localCount: 3
? }
}
?// ...
?computed: {
...mapState({
? ? ?count: state => state.count,
? ? ?token: state => state.token,
? ? ?countA: 'count',
? ? ?countFuc(state) {
? ? ? ?return state.count + this.localCount
? ? }
? })
}
}
~~~
## getter
類似于計算屬性computed,你可以將它當做一個屬性使用,也可以將它修飾后再使用;除此之外,在獲取 `state` 中數據嵌套較深的數據時,它極其有用(對比直接獲取state值的復雜度)
應用場景: 獲取請求url的域名端口、多頁面獲取同一個限制數據
~~~
export default 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)
? },
? ?doneTodosCount: (state, getters) => {
? ? ?return getters.doneTodos.length
? }
}
})
~~~
### mapGetters 輔助函數
類似于 `mapState` , 將 `computed` 下 `...mapGetters` 中的名稱映射為 `store.getters.xxx`
~~~
export default {
?// ...
?mounted() {
? ?console.log('store.getters.doneTodos', this.doneTodosCount)
? ?console.log('store.getters.doneTodosCount', this.doneTodos)
}
?computed: {
? ?...mapGetters([
? ? ?'doneTodosCount',
? ? ?'doneTodos'
? ? ?// ...
? ])
? ?// 也可以像這樣更改名稱
? ?// ...mapGetters({
? ?// ? toDoCount: 'doneTodosCount'
? ?// })
}
}
~~~
## mutation
是更改vuex狀態的唯一方法,mutation必須是同步函數
~~~
export default new Vuex.Store({
?state: {
? ?count: 1
},
?mutations: {
? ?increment(state, payload) {
? ? ?state.count += payload
? },
? ?clcrement(state, payload) {
? ? ?state.count -= payload
? }
}
})
~~~
~~~
// 提交mutation
this.$store.commit('increment', 3)
~~~
### mapMutations 輔助函數
使用原理與之前的輔助函數一樣
在組件中提交mutation
~~~
export default {
?methods: {
? ?...mapMutations([
? ? ?'increment'
? ]),
? ?...mapMutations({
? ? ?dele: 'clcrement'
? }),
? ?handleFuc() {
? ? ?this.increment(4)
? ? ?// this.dele(3)
? }
}
}
~~~
## action
使用方式與mutation相似,不同點:
* action提交mutation,而不是直接更改狀態
* action可以包含異步操作
可以利用 `async/await` 組合action
~~~
// 假設 getData() 和 getOtherData() 返回的是 Promise
?
actions: {
?async actionA ({ commit }) {
? ?commit('gotData', await getData())
},
?async actionB ({ dispatch, commit }) {
? ?await dispatch('actionA') // 等待 actionA 完成
? ?commit('gotOtherData', await getOtherData())
}
}
~~~
~~~
// 分發action
this.$store.dispatch('actionA').then(() => {
?// ...
})
~~~
### mapActions 輔助函數
在組件中分發action,用法與mapMutations基本一致
## module
模塊可以將vuex進行分割,每個分割后的模塊擁有自己的 `state`、`mutation`、`action`、`getter`, 甚至是嵌套子模塊,在這store對象比較臃腫時非常有用,而且分割會使分類更加清晰
~~~
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import test from './modules/user'
import getters from './getters'
?
Vue.use(Vuex)
?
export default new Vuex.Store({
?modules: {
? ?user,
? ?test
},
?getters
})
~~~