vuex是專門爲vue.js開發的狀態管理模式,它將全部組件的狀態集中的存儲在一塊兒,而且用相應的規則使這些狀態以一種可預測的方式發生改變。vue
前面說到vuex是專門爲vue.js開發的狀態管理模式,那麼究竟什麼是「狀態管理模式」呢? 以我目前對狀態的理解就是組件在某個時刻呈現出的視圖、數據的狀態。在vue的項目開發中咱們常常會遇到多個組件共享某個狀態。即:多個視圖依賴同一組件 或者 不一樣視圖的行爲須要改變同一狀態。
對於這種狀況父子組件以前經過props進行傳參是很繁瑣的,同時兄弟組件是沒辦法作到的。而且不一樣視圖之間只能經過事件觸發或直接引用的方式傳遞數據。這顯然是很麻煩的。
所以就有了vuex,他將組件的全部狀態抽離出來,存儲在全局的一個倉庫裏,這樣無論組件在哪一個位置均可以獲取到狀態或者觸發行爲。vuex就像一個巨大的倉庫同樣能夠爲咱們存儲着全部組件的狀態和改變狀態的行爲,同時維持着視圖和狀態之間的獨立性,使得代碼變得結構更加清晰且易維護。vuex
npm install vuex --savenpm
import Vuex from 'vuex'
vue.use(Vuex)數組
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
複製代碼
// 建立一個 Counter 組件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
複製代碼
因爲 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態promise
store.commit('increment')
複製代碼
注意:改變狀態的惟一方式就是經過commit提交mutationbash
//引入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
}
})
}
複製代碼
當映射的計算屬性的名稱與 state 的子節點名稱相同時,咱們也能夠給 mapState 傳一個字符串數組。app
computed: mapState([
// 映射 this.count 爲 store.state.count
'count'
])
複製代碼
//Getter 接受 state 做爲其第一個參數,接受其餘 getter 做爲第二個參數:
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.doneTodos // -> [{ id: 1, text: '...', done: true }]
複製代碼
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
複製代碼
//它會接受 state 做爲第一個參數:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變動狀態
state.count++
}
}
})
複製代碼
兩種提交方式async
//方式一
store.commit('increment', {
amount: 10
})
*******
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
//方式二 ——對象風格的提交方式
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
*******
store.commit({
type: 'increment',
amount: 10
})
複製代碼
註冊一個簡單的action函數
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
//action接受一個和store有相同屬性和方法的context 對象
//所以你能夠調用 context.commit 提交一個 mutation
//經過 context.state 和 context.getters 來獲取 state 和 getters
actions: {
increment (context) {
context.commit('increment')
}
}
})
複製代碼
store.dispatch('increment')
// 以載荷形式分發
store.dispatch('incrementAsync', {
amount: 10
})
// 以對象形式分發
store.dispatch({
type: 'incrementAsync',
amount: 10
})
複製代碼
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('actionA').then(() => {
// 處理Action返回的promise
})
複製代碼
// 假設 getData() 和 getOtherData() 返回的是 Promise
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
複製代碼
const moduleA = {
state: { count: 0 },
mutations: {
increment (state) {
// 這裏的 `state` 對象是模塊的局部狀態
state.count++
}
},
getters: {
doubleCount (state) {
return state.count * 2
}
}
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態
複製代碼
const store = new Vuex.Store({
modules: {
account: {
namespaced: true,
// 模塊內容(module assets)
state: { ... }, // 模塊內的狀態已是嵌套的了,使用 `namespaced` 屬性不會對其產生影響
getters: {
isAdmin () { ... } // -> getters['account/isAdmin']
},
actions: {
login () { ... } // -> dispatch('account/login')
},
mutations: {
login () { ... } // -> commit('account/login')
},
// 嵌套模塊
modules: {
// 繼承父模塊的命名空間
myPage: {
state: { ... },
getters: {
profile () { ... } // -> getters['account/profile']
}
},
// 進一步嵌套命名空間
posts: {
namespaced: true,
state: { ... },
getters: {
popular () { ... } // -> getters['account/posts/popular']
}
}
}
}
}
})
複製代碼