vuex是什麼?
“Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。” -----援引自 vuex官網
一、安裝
npm install vuex --save
二、核心概念
state:單一狀態樹,用一個對象就包含了全部的應用層級狀態。
Mutation:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,並且它會接受 state 作爲第一個參數,第二個參數爲傳入的值:
const store = new Vuex.Store({
state: {
value: 1
},
mutations: {
increment (state, newVal) {
// 變更狀態
state.value = newVal
}
}
})
Action:
Action 類似於 mutation,不同在於:
- Action 提交的是 mutation,而不是直接變更狀態。
- Action 可以包含任意異步操作。
第一個參數爲context對象,第二個參數爲傳入參數:
const store = new Vuex.Store({
state: {
value: 1
},
mutations: {
increment (state, newVal) {
// 變更狀態
state.value = newVal
}
},
actions: {
increment (context, newVal) {
context.commit('increment', newVal)
}
}
})
Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit
提交一個 mutation
三、項目結構
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API請求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我們組裝模塊並導出 store 的地方
├── actions.js # 根級別的 action
├── mutations.js # 根級別的 mutation
四、具體使用
接上圖結構
在 main.js 中引用
import store from './store' // 會自動尋找store文件夾下的index.js文件
...
new Vue({
store,
...
})
其中index.js 爲組裝模塊並導出store的地方
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './action'
import mutations from './mutations'
Vue.use(Vuex)
const state = {
name: '李白',
age: '100',
poem: '李白乘舟將欲行'
}
export default new Vuex.Store({
state,
actions,
mutations
})
actions.js 集中所有actions
export default {
changeUser(context, user) {
context.commit('changeUser', user);
}
...
}
mutations.js 集中所有mutations
export default {
changeUser(state, user) {
state.name = user;
}
...
}
使用方法:
1.使用 this.$store.dispatch() 觸發 相應action
methods: {
addList () {
...
this.$store.dispatch('changeUser', this.title);
...
}
}
2.進入actions.js 中的 changeUser ,接着通過 context.commit() 提交一個 mutation changeUser
changeUser(context, user) {
context.commit('changeUser', user);
}
3.進入 mutations.js 中的 changeUser,通過 state.name = user 修改狀態值。
changeUser(state, user) {
state.name = user;
}
至此,完成。
五、 補充函數
1. 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
}
})
}
當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給 mapState 傳一個字符串數組。
computed: mapState([
// 映射 this.count 爲 store.state.count
'count'
])
2. mapAction
使用 mapActions
輔助函數將組件的 methods 映射爲 store.dispatch
調用(需要先在根節點注入 store
):
import { mapActions } from 'vuex'
export default {
// ...
methods: {
addList () {
...
// this.$store.dispatch('changeUser', this.title);
// 上邊這句話可以用下邊這句代替
thiS.increment('changeUser', this.title)
...
}
...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')`
})
}
}