Vuex是什么?
Vuex是一個專為Vue.js應用程序開發(fā)的狀態(tài)管理模式
Vuex是全局的狀態(tài)管理
Vuex用來做什么跪帝?
Vuex用于組件之間的傳值,多個組件共享數(shù)據(jù)
Vuex的數(shù)據(jù)是響應式的,當我們在A組件更新了某個狀態(tài)膀估,來到B組件躁倒,B組件會動態(tài)更新
State
State
用來存儲狀態(tài)
在組件中獲取Vuex
狀態(tài)
由于Vuex
的狀態(tài)存儲是響應式的荞怒,從store
實例中讀取狀態(tài)最簡單的方法就是在計算屬性
中返回某個狀態(tài):
computed: {
count: () => store.state.count
// or 將狀態(tài)從根組件“注入”到每一個子組件中 Vue.use(Vuex)
count: () => this.$store.state.count
},
mapState 獲取方式
import { mapState } form 'vuex'
computed: {
...mapState({
// 1. 基礎用法 store/index.js
isLogin: (state) => state.isLogin
// 2. 使用模塊 store/modules/user.js
isLogin: (state) => state.user.isLogin
}),
},
Getters
Getters
類似計算屬性,只有當它的依賴發(fā)生改時才會重新求值
Getter 接受 state 作為其第一個參數(shù):
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)
}
}
})
在組件中使用
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
mapGetters 獲取方式
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
// 使用Modules store/user.js
...mapGetters('user',[
'increment',
'incrementBy',
// ...
])
}
}
Mutations
更改store
中狀態(tài)的唯一方法是mutations
mutations
第一個參數(shù)是state
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變更狀態(tài)
state.count++
}
}
})
調用方法
store.commit('increment')
你可以向store.commit
傳入額外的參數(shù)
// ...
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
記住 Mutation 必須是同步函數(shù)
在組件中提交 Mutation
computed: {
doneTodosCount () {
return this.$store.commit('increment')
}
}
mapMutations 方式提交
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapMutations([
'increment',
'incrementBy',
// ...
])
// 使用Modules store/user.js
...mapMutations('user',[
'increment',
'incrementBy',
// ...
])
}
}
Action
Action 類似于 mutation秧秉,不同在于:
- Action 提交的是 mutation褐桌,而不是直接變更狀態(tài)。
- Action 可以包含任意異步操作象迎。
注冊一個簡單的 action:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象荧嵌,因此你可以調用context.commit
提交一個 mutation呛踊,或者通過context.state
和context.getters
來獲取 state 和 getters。
實踐中啦撮,我們會經常用到 ES2015 的 參數(shù)解構 (opens new window)來簡化代碼
actions: {
increment ({ commit }) {
commit('increment')
}
}
在組件中觸發(fā) Action
methods: {
increment () {
this.$store.dispatch('increment')
}
}
mapActions 方式觸發(fā)
import { mapActions } from 'vuex'
export default {
// ...
methods: {
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapActions([
'increment',
'incrementBy',
// ...
])
// 使用Modules store/user.js
...mapActions('user',[
'increment',
'incrementBy',
// ...
])
}
}
組合 Action
有時候需要組合多個action
谭网,例如有時候需要在actionB中調用actionA
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
利用 async / await ,我們可以如下組合 action:
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
// ...
}
}
Modules
當應用變得非常復雜時赃春,store 對象就有可能變得相當臃腫愉择。
modules 將 store 分割成模塊。
每個模塊擁有自己的 state织中、mutation囤热、action、getter闷哆、甚至是嵌套子模塊礁遵。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
項目使用案例
@/store/modules/user.js :
export default {
namespaced: true,
state: {
// 存儲狀態(tài)
isLogin: false
},
mutations: {
// 修改狀態(tài)
SET_ISLOGIN(state, val) {
state.isLogin = val
}
},
actions: {
// 異步操作
login({ commit }, query) {
api.login({
code: query.code,
iv: query.iv
}).then(res => {
commit('SET_ISLOGIN', true)
})
}
}
}
@/store/index.js :
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
// 安裝 Vuex
Vue.use(Vuex)
// 創(chuàng)建一個 store
export default new Vuex.Store({
modules: {
user,
// ...
}
})
@/main.js :
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from '@/store';
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');