什么是Vuex?
Vuex 是专门为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
在大型单页应用中,当多个组件共享状态时,简单的单向数据流可能会变得难以维护。Vuex 通过将共享状态提取出来,以一个全局单例模式管理,解决了这个问题。
核心概念
1. State(状态)
State 是 Vuex 的核心,包含了应用中需要共享的数据。它类似于组件中的 data,但是是全局共享的。
const store = new Vuex.Store({
state: {
count: 0,
user: null
}
})
2. Getters(获取器)
Getters 可以看作是 store 的计算属性,用于从 state 中派生出一些状态。
const store = new Vuex.Store({
getters: {
doubleCount: state => state.count * 2,
currentUser: state => state.user
}
})
3. Mutations(变更)
Mutations 是更改 Vuex store 中状态的唯一方法。它们是同步的事务。
const store = new Vuex.Store({
mutations: {
increment(state) {
state.count++
},
setUser(state, user) {
state.user = user
}
}
})
4. Actions(动作)
Actions 类似于 mutations,不同之处在于:
Actions 提交的是 mutations,而不是直接变更状态
Actions 可以包含任意异步操作
const store = new Vuex.Store({
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
},
fetchUser({ commit }, userId) {
return api.fetchUser(userId).then(user => {
commit('setUser', user)
})
}
}
})
5. Modules(模块)
当应用变得复杂时,store 对象可能会变得臃肿。Vuex 允许我们将 store 分割成模块。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA
}
})
Vuex 的优势
集中管理状态:所有共享状态集中在一个地方管理,易于理解和维护
状态变更可追踪:每次状态变更都有记录,方便调试
组件通信简化:避免了复杂的组件间通信(如多层 props 传递或事件冒泡)
数据流清晰:强制实施单向数据流,使代码更结构化
插件系统:支持插件扩展,如持久化、日志等
何时使用 Vuex?
虽然 Vuex 很有用,但并不是所有应用都需要它。Vuex 适用于:
大型单页应用
多个视图依赖同一状态
来自不同视图的行为需要变更同一状态
对于简单的应用,使用简单的 store 模式可能就足够了。
示例:购物车实现
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
cart: [],
products: [
{ id: 1, name: 'Product 1', price: 100 },
{ id: 2, name: 'Product 2', price: 200 }
]
},
getters: {
cartTotal: state => {
return state.cart.reduce((total, item) => total + item.price * item.quantity, 0)
},
cartItemCount: state => {
return state.cart.reduce((count, item) => count + item.quantity, 0)
}
},
mutations: {
addToCart(state, product) {
const item = state.cart.find(item => item.id === product.id)
if (item) {
item.quantity++
} else {
state.cart.push({ ...product, quantity: 1 })
}
},
removeFromCart(state, productId) {
const index = state.cart.findIndex(item => item.id === productId)
if (index !== -1) {
state.cart.splice(index, 1)
}
}
},
actions: {
checkout({ commit, state }) {
return new Promise((resolve) => {
// 模拟API调用
setTimeout(() => {
console.log('Checkout complete', state.cart)
commit('clearCart')
resolve()
}, 1000)
})
},
clearCart({ commit }) {
commit('clearCart')
}
}
})
在组件中使用 Vuex
<template>
<div>
<h2>Products</h2>
<div v-for="product in products" :key="product.id">
{{ product.name }} - ${{ product.price }}
<button @click="addToCart(product)">Add to Cart</button>
</div>
<h2>Cart ({{ cartItemCount }}) - Total: ${{ cartTotal }}</h2>
<div v-for="item in cart" :key="item.id">
{{ item.name }} x {{ item.quantity }}
<button @click="removeFromCart(item.id)">Remove</button>
</div>
<button @click="checkout" :disabled="!cart.length">Checkout</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapState(['products', 'cart']),
...mapGetters(['cartTotal', 'cartItemCount'])
},
methods: {
...mapActions(['addToCart', 'removeFromCart', 'checkout'])
}
}
</script>
Vuex 最佳实践
模块化组织:大型应用应该按功能将 store 分割成模块
遵循命名规范:使用常量替代 mutation 和 action 的事件类型
避免直接修改 state:始终通过 mutations 修改 state
合理使用 getters:对于派生状态使用 getters
异步操作放在 actions 中:保持 mutations 同步
考虑使用辅助函数:mapState, mapGetters, mapActions 等简化代码
Vuex 与 Composition API
在 Vue 3 中,可以使用 Composition API 与 Vuex 交互:
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup() {
const store = useStore()
const count = computed(() => store.state.count)
const doubleCount = computed(() => store.getters.doubleCount)
const increment = () => store.commit('increment')
const incrementAsync = () => store.dispatch('incrementAsync')
return {
count,
doubleCount,
increment,
incrementAsync
}
}
}
总结
Vuex 为 Vue.js 应用提供了强大的状态管理能力,特别适合中大型复杂应用。通过集中管理状态、明确的修改规则和良好的开发工具支持,Vuex 能够帮助开发者构建更可维护、更可预测的应用程序。随着 Vue 生态的发展,Vuex 仍然是许多项目的首选状态管理方案。