在 Vue.js 开发中,当应用规模逐渐扩大,组件间的状态共享和通信就会变得复杂。这时,Vuex 作为 Vue 的官方状态管理库,能帮我们更好地管理应用状态。
一、Vuex 核心属性概述
Vuex 的核心由State、Mutation、Action、Getter和Module五个部分组成,它们相互配合,构成了 Vuex 的状态管理机制。
二、State:存储状态的容器
State是 Vuex 中用于存储应用状态的地方,它就像一个全局的数据源,供整个应用的组件共享。
传统获取方法
在组件中,可以通过this.$store.state来获取状态。例如,我们在 store 中定义了一个count状态:
// store/index.js
const store = new Vuex.Store({
state: {
count: 0
}
})
在组件中获取:
// 组件中
console.log(this.$store.state.count); // 输出0
辅助函数获取方法(需先引入)
import { mapState } from 'vuex'
然后在组件的computed属性中使用:
computed: {
...mapState([
'count' // 将this.count映射为this.$store.state.count
])
}
也可以使用对象形式,对状态进行重命名:
computed: {
...mapState({
myCount: 'count' // 将this.myCount映射为this.$store.state.count
})
}
三、Mutation:修改状态的唯一途径
Mutation用于修改State中的状态,它必须是同步函数。通过Mutation来修改状态,可以方便地进行状态追踪和调试。
传统调用方法
首先,在 store 中定义Mutation:
// store/index.js
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
// 变更状态
state.count++
},
incrementBy (state, payload) {
state.count += payload.amount
}
}
})
然后,在组件中通过this.$store.commit调用:
// 组件中
this.$store.commit('increment')
this.$store.commit('incrementBy', { amount: 5 })
辅助函数调用方法(需先引入)
import { mapMutations } from 'vuex'
在组件的methods中使用:
methods: {
...mapMutations([
'increment' // 将this.increment()映射为this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 将this.add()映射为this.$store.commit('increment')
})
}
四、Action:处理异步操作
Action类似于Mutation,但它可以处理异步操作。Action通过提交Mutation来修改状态,而不是直接变更状态。
传统调用方法
在 store 中定义Action
// store/index.js
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
},
incrementByAsync ({ commit }, payload) {
setTimeout(() => {
commit('incrementBy', payload)
}, 1000)
}
}
})
在组件中通过this.$store.dispatch调用
// 组件中
this.$store.dispatch('incrementAsync')
this.$store.dispatch('incrementByAsync', { amount: 5 })
辅助函数调用方法
mapActions辅助函数可以将组件中的方法映射为store.dispatch调用。引入:
import { mapActions } from 'vuex'
在组件的methods中使用:
methods: {
...mapActions([
'incrementAsync' // 将this.incrementAsync()映射为this.$store.dispatch('incrementAsync')
]),
...mapActions({
asyncAdd: 'incrementAsync' // 将this.asyncAdd()映射为this.$store.dispatch('incrementAsync')
})
}
五、Getter:对状态进行加工处理
Getter用于对State中的数据进行加工处理,形成新的数据。它就像 Vue 中的计算属性一样,会根据依赖的状态自动更新。
传统获取方法
在 store 中定义Getter:
// store/index.js
const store = new Vuex.Store({
state: {
count: 0,
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
countDouble: state => {
return state.count * 2
}
}
})
在组件中通过this.$store.getters获取:
// 组件中
console.log(this.$store.getters.doneTodos)
console.log(this.$store.getters.countDouble)
辅助函数获取方法
mapGetters辅助函数用于将store中的getter映射到组件的计算属性中。引入:
import { mapGetters } from 'vuex'
在组件的computed中使用:
computed: {
...mapGetters([
'doneTodos',
'countDouble'
]),
...mapGetters({
myDoneTodos: 'doneTodos'
})
}
六、Module:拆分复杂状态
当应用变得复杂时,State中的状态可能会非常多,此时可以使用Module将Store拆分为多个模块。每个模块拥有自己的State、Mutation、Action、Getter,甚至可以嵌套子模块。
modules 的好处
状态管理更清晰:将不同功能或业务领域的状态拆分到不同的模块中,使代码结构更清晰,便于维护和管理。
提高代码复用性:模块可以被多个组件共享和复用,减少了代码的冗余。
便于团队协作:不同的开发人员可以负责不同的模块,提高了团队协作的效率。
基本使用方法
定义一个模块:
// store/modules/cart.js
const cart = {
state: {
items: []
},
mutations: {
addItem (state, item) {
state.items.push(item)
}
},
actions: {
addItemAsync ({ commit }, item) {
setTimeout(() => {
commit('addItem', item)
}, 1000)
}
},
getters: {
itemCount: state => {
return state.items.length
}
}
}
export default cart
在 store 中引入模块:
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
cart
}
})
export default store
在组件中访问模块中的状态、调用模块中的Mutation和Action:
// 访问状态
console.log(this.$store.state.cart.items)
// 调用Mutation
this.$store.commit('addItem', { id: 1, name: '商品1' })
// 调用Action
this.$store.dispatch('addItemAsync', { id: 2, name: '商品2' })
// 获取Getter
console.log(this.$store.getters.itemCount)
七、总结
Vuex 的五大核心属性State、Mutation、Action、Getter和Module各自有着独特的功能和作用,它们相互配合,为 Vue 应用提供了高效、清晰的状态管理方案。通过传统的调用方法和辅助函数,我们可以方便地在组件中使用这些属性。而Module则为复杂应用的状态管理提供了更好的解决方案,使代码结构更清晰,便于维护和扩展。