一、Vuex 概述
作用:Vuex 是 Vue.js 的 状态管理库,用于集中管理组件间共享的状态(如用户信息、全局配置)。
适用场景:中大型单页应用(SPA),解决多组件共享状态时的数据一致性问题。
核心思想:单向数据流 + 集中式状态管理。
Vuex 与 Pinia:
Vuex 是 Vue 2 官方推荐的状态管理库;Pinia 是 Vue 3 的轻量级替代方案,但 Vuex 仍可兼容 Vue 3。
二、核心概念
1. State(状态)
存储应用层的共享状态,类似组件的 data。
定义:
const store = new Vuex.Store({
state: {
count: 0,
user: null
}
})
访问:
this.$store.state.count // 组件中直接访问
// 或通过 mapState 辅助函数
computed: {
...mapState(['count', 'user'])
}
2. Mutations(变更)
唯一修改 state 的方式,必须是同步函数。
定义:
mutations: {
increment(state) {
state.count++
},
setUser(state, user) {
state.user = user
}
}
触发:
this.$store.commit('increment') // 直接触发
this.$store.commit('setUser', { name: 'Alice' }) // 带参数
3. Actions(动作)
处理异步操作(如 API 请求),提交 mutation 修改 state。
定义:
actions: {
async fetchUser({ commit }, userId) {
const user = await api.getUser(userId)
commit('setUser', user)
}
}
触发:
this.$store.dispatch('fetchUser', 123) // 带参数
4. Getters(计算属性)
对 state 进行派生计算,类似组件的 computed。
定义:
getters: {
doubleCount(state) {
return state.count * 2
}
}
访问:
this.$store.getters.doubleCount
// 或通过 mapGetters
computed: {
...mapGetters(['doubleCount'])
}
5. Modules(模块)
将大型 store 拆分为多个模块,每个模块拥有独立的 state/mutations/actions/getters。
定义:
const userModule = {
namespaced: true, // 开启命名空间
state: { ... },
mutations: { ... }
}
const store = new Vuex.Store({
modules: {
user: userModule
}
})
访问模块状态:
this.$store.state.user // 模块的 state
this.$store.getters['user/doubleCount'] // 模块的 getter
this.$store.commit('user/setUser') // 模块的 mutation
this.$store.dispatch('user/fetchUser') // 模块的 a
三、基础使用
1. 安装与配置
npm install vuex
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
})
// main.js
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
2. 组件中绑定
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count']),
...mapGetters(['doubleCount'])
},
methods: {
...mapActions(['fetchUser']),
increment() {
this.$store.commit('increment')
}
}
}