一篇文章讓你徹底搞懂vuex
前言
以下是針對(duì)“Vuex詳解”的一篇萬(wàn)字級(jí)全面教程(實(shí)際字?jǐn)?shù)約6000+),基于2025–2026年Vue.js開發(fā)視角。Vuex是Vue.js的經(jīng)典狀態(tài)管理庫(kù),雖然Vue 3+官方推薦Pinia作為替代,但Vuex在大量遺留項(xiàng)目和中大型應(yīng)用中仍廣泛使用(Vuex 4兼容Vue 3)。我會(huì)從基礎(chǔ)概念入手,逐步深入到高級(jí)用法、源碼簡(jiǎn)析、最佳實(shí)踐、面試高頻,以及與Pinia的對(duì)比。內(nèi)容實(shí)用、帶代碼示例、表格對(duì)比,適合初學(xué)者到中高級(jí)開發(fā)者。
如果你是Vue 2用戶,從“一、二”部分看起;Vue 3用戶,注意“三”中的兼容點(diǎn);想遷移Pinia,看“八”。如果需要代碼倉(cāng)庫(kù)或特定版本差異,直接回復(fù)我。
一、Vuex是什么?為什么需要它?(核心概念)
1.1 Vuex的定義
Vuex是一個(gè)專為Vue.js應(yīng)用設(shè)計(jì)的狀態(tài)管理模式 + 庫(kù),它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)(State),并以相應(yīng)的規(guī)則保證狀態(tài)以可預(yù)測(cè)的方式發(fā)生變化。
- 核心靈感:借鑒Flux和Redux,解決Vue中組件間數(shù)據(jù)共享問題(如props鉆透、事件總線亂用)。
- 官方定位:中大型單頁(yè)應(yīng)用(SPA)的全局狀態(tài)管理器。小項(xiàng)目用Provide/Inject或Composition API就夠。
- 版本演進(jìn)(2026年現(xiàn)狀):
- Vuex 3.x:Vue 2默認(rèn)
- Vuex 4.x:Vue 3兼容版(支持Composition API,但非首選)
- 未來(lái):Vuex不會(huì)大更新,Pinia是Vue生態(tài)新寵(更輕、更類型友好)。
1.2 為什么用Vuex?(問題解決)
在Vue中,組件間通信常見痛點(diǎn):
- Props + Emit:父子通信OK,但多層嵌套或兄弟組件麻煩。
- Event Bus:全局事件易亂,難追蹤。
- LocalStorage:異步、不響應(yīng)式。
Vuex解決:
- 單向數(shù)據(jù)流:State → View → Actions → Mutations → State(循環(huán))。
- 集中管理:所有狀態(tài)一處修改,全局可訪問。
- 響應(yīng)式:基于Vue的Reactivity系統(tǒng),狀態(tài)變就自動(dòng)更新視圖。
- 可預(yù)測(cè):Mutations同步修改,Actions處理異步。
不適合場(chǎng)景:小項(xiàng)目(用ref/reactive + provide/inject);純靜態(tài)頁(yè)。
1.3 Vuex核心模塊(五大件)
Vuex Store = State + Mutations + Actions + Getters + Modules
| 模塊 | 作用 | 同步/異步 | 調(diào)用方式 |
|---|---|---|---|
| State | 存儲(chǔ)狀態(tài)數(shù)據(jù) | — | this.$store.state.xxx |
| Mutations | 修改State的唯一方式(同步) | 同步 | commit(‘mutationName’) |
| Actions | 處理異步邏輯,提交Mutations | 異步 | dispatch(‘actionName’) |
| Getters | 計(jì)算屬性(派生狀態(tài)) | — | this.$store.getters.xxx |
| Modules | 模塊化拆分Store(命名空間) | — | 按模塊訪問 |
數(shù)據(jù)流圖(文本版):
Actions (異步) → Mutations (同步修改State) → State → Getters (計(jì)算) → View (渲染) ↑ 用戶交互/事件
二、安裝 & 基本使用(Vue 3視角)
2.1 安裝Vuex(2026推薦)
- Vue 3:
npm install vuex@next(Vuex 4.x) - Vue 2:
npm install vuex
2.2 創(chuàng)建Store
// store/index.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0,
user: { name: 'Grok' }
},
mutations: {
increment(state) {
state.count++;
},
setUser(state, payload) {
state.user.name = payload;
}
},
actions: {
asyncIncrement({ commit }) { // context對(duì)象
return new Promise(resolve => {
setTimeout(() => {
commit('increment');
resolve();
}, 1000);
});
}
},
getters: {
doubleCount: state => state.count * 2,
fullName: (state, getters) => `${state.user.name} (double: ${getters.doubleCount})`
}
});
2.3 在Vue中掛載 & 使用
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
createApp(App).use(store).mount('#app');
組件中使用:
<template>
<div>
<p>Count: {{ count }}</p> <!-- 響應(yīng)式 -->
<p>Double: {{ doubleCount }}</p>
<button @click="increment">+1</button>
<button @click="asyncIncrement">Async +1</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count']), // 簡(jiǎn)寫state.count
...mapGetters(['doubleCount'])
},
methods: {
...mapMutations(['increment']), // this.increment() → commit
...mapActions(['asyncIncrement']) // this.asyncIncrement() → dispatch
}
}
</script>
輔助函數(shù)(mapXXX):簡(jiǎn)化訪問,推薦在computed/methods中使用。
2.4 嚴(yán)格模式(Strict Mode)
- 開發(fā)環(huán)境開啟:
strict: true(Store選項(xiàng)) - 強(qiáng)制所有State修改必須通過(guò)Mutations,否則報(bào)錯(cuò)(防直接state.xxx = yyy)。
三、Vue 3兼容 & Composition API用法
Vuex 4支持Vue 3的setup:
<script setup>
import { useStore } from 'vuex';
import { computed } from 'vue';
const store = useStore();
const count = computed(() => store.state.count);
const doubleCount = computed(() => store.getters.doubleCount);
const increment = () => store.commit('increment');
const asyncIncrement = () => store.dispatch('asyncIncrement');
</script>
關(guān)鍵:Vue 3中,Vuex的響應(yīng)式基于Vue的Reactivity,但Pinia更原生支持setup(無(wú)this)。
四、進(jìn)階:Modules模塊化(大型項(xiàng)目必備)
大Store拆分成Modules,避免單一文件臃腫。
// store/index.js
import userModule from './modules/user';
export default createStore({
modules: {
user: userModule // 模塊名
}
});
// modules/user.js
export default {
namespaced: true, // 開啟命名空間(推薦,避免沖突)
state: { name: 'Grok' },
mutations: { setName(state, payload) { state.name = payload; } },
actions: { asyncSetName({ commit }, payload) { commit('setName', payload); } },
getters: { upperName: state => state.name.toUpperCase() }
};
訪問:
- 無(wú)命名空間:
store.state.user.name - 有命名空間:
commit('user/setName', 'NewName')、getters['user/upperName']
最佳實(shí)踐:每個(gè)功能一個(gè)模塊(如user、cart、auth),始終開啟namespaced。
五、Actions & Mutations深入(異步 & 參數(shù))
5.1 Mutations:同步純函數(shù)
- 必須同步:防狀態(tài)不可預(yù)測(cè)。
- 參數(shù):state(第一個(gè)),payload(可選負(fù)載)。
5.2 Actions:異步容器
- 可異步:API調(diào)用、Promise。
- context對(duì)象:{ state, getters, commit, dispatch, rootState, rootGetters }
- 返回Promise:便于.then處理。
示例:
actions: {
async fetchUser({ commit }) {
const res = await fetch('/api/user');
const data = await res.json();
commit('setUser', data);
}
}
5.3 組合Actions
actions: {
actionA({ dispatch }) { return dispatch('actionB'); },
actionB() { /* ... */ }
}
六、Getters & 插件(計(jì)算 & 擴(kuò)展)
6.1 Getters:Store的computed
- 參數(shù):state(第一個(gè)),getters(可選),rootState,rootGetters。
- 緩存:依賴不變不重算。
6.2 插件(Plugins)
- 擴(kuò)展Store:日志、持久化。
示例(簡(jiǎn)單日志插件):
const myPlugin = store => {
store.subscribe((mutation, state) => {
console.log(`Mutation: ${mutation.type}, Payload: ${mutation.payload}, New State: ${state}`);
});
};
// 使用
createStore({ plugins: [myPlugin] });
熱門插件(2026仍活躍):
- vuex-persistedstate:本地存儲(chǔ)State(localStorage)。
- vuex-orm:數(shù)據(jù)庫(kù)式管理(關(guān)系模型)。
七、源碼簡(jiǎn)析 & 性能優(yōu)化(高級(jí))
7.1 核心源碼邏輯
- Store類:new Vue({ data: { $$state: initialState } }) → 借Vue響應(yīng)式。
- install:Vue.mixin注入$store。
- commit:執(zhí)行mutations,觸發(fā)響應(yīng)。
- dispatch:執(zhí)行actions,支持Promise鏈。
7.2 性能優(yōu)化
- 避免深層嵌套:用Modules扁平化。
- Getters緩存:多用Getters少計(jì)算。
- 批量commit:異步操作后一次性提交。
- Immutable:用Object.assign或spread避免直接改state。
- Devtools:Chrome Vue Devtools監(jiān)控性能。
- Vue 3:Vuex響應(yīng)式開銷比Pinia高,考慮遷移。
7.3 常見坑
- 直接改State:嚴(yán)格模式報(bào)錯(cuò),生產(chǎn)崩潰。
- 異步Mutations:無(wú)效,用Actions。
- 循環(huán)依賴:Getters/Actions別互調(diào)無(wú)限循環(huán)。
- 類型安全:Vuex無(wú)內(nèi)置TS,用vuex-module-decorators或Pinia。
八、Vuex vs Pinia對(duì)比(2026遷移指南)
| 方面 | Vuex | Pinia | 遷移建議 |
|---|---|---|---|
| 設(shè)計(jì) | Mutations/Actions分離 | 統(tǒng)一Actions(同步/異步混用) | Pinia更簡(jiǎn) |
| API | this.$store | defineStore + setup風(fēng)格 | Vue3首選 |
| 模塊化 | Modules + namespaced | 每個(gè)Store獨(dú)立文件 | 易拆分 |
| 類型支持 | 一般(需插件) | 原生TS | TS項(xiàng)目遷 |
| 體積 | 較大 | 更輕(無(wú)Mutations) | 小項(xiàng)目遷 |
| Devtools | 支持 | 更好(時(shí)間旅行) | — |
| 官方推薦 | Vue2默認(rèn),Vue3兼容 | Vue3官方狀態(tài)管理 | 新項(xiàng)目Pinia |
遷移步驟:
- 安裝Pinia:
npm i pinia - 創(chuàng)建Store:
defineStore('user', { state: () => ({ name: '' }), actions: { setName() {} } }) - 用
useUserStore()替換$store - Mutations → Actions,Getters不變。
九、最佳實(shí)踐 & 面試高頻(生產(chǎn)Checklist)
9.1 最佳實(shí)踐
- 小State:只存全局共享數(shù)據(jù),局部用組件state。
- 常量化類型:用const INCREMENT = ‘increment’ 防拼寫錯(cuò)。
- 異步全Actions:API、定時(shí)器等。
- 模塊化從開始:項(xiàng)目一上來(lái)就拆Modules。
- 測(cè)試:用vuex-test-utils測(cè)試Mutations/Actions。
- 持久化:敏感數(shù)據(jù)用vuex-persistedstate + encryption。
- 監(jiān)控:集成Sentry日志異常State。
9.2 面試高頻題(2025–2026)
- Vuex數(shù)據(jù)流?(State→View→Actions→Mutations→State)
- Mutations為什么必須同步?(可預(yù)測(cè)、易調(diào)試)
- Actions返回Promise怎么用?(dispatch.then())
- mapState/mapGetters怎么工作?(返回computed對(duì)象)
- Vuex在Vue3的痛點(diǎn)?(this依賴,Pinia無(wú))
- 如何實(shí)現(xiàn)State持久化?(插件subscribe + localStorage)
- Modules命名空間的作用?(防沖突,模塊隔離)
9.3 擴(kuò)展資源
- 官方文檔:vuex.vuejs.org(2026仍維護(hù))
- GitHub示例:vuejs/vuex/tree/4.0/examples
- 書籍:《Vue.js設(shè)計(jì)與實(shí)現(xiàn)》狀態(tài)管理章節(jié)
- 社區(qū):Reddit r/vuejs、StackOverflow
這篇詳解讓你從0到1徹底搞懂Vuex。如果你想深入某個(gè)模塊(如Actions異步鏈?zhǔn)健S支持)、或?qū)Ρ萊edux/Pinia的代碼,直接告訴我!
到此這篇關(guān)于vuex的文章就介紹到這了,更多相關(guān)vuex詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Nuxt內(nèi)導(dǎo)航欄的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了詳解Nuxt內(nèi)導(dǎo)航欄的兩種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Vue+vite創(chuàng)建項(xiàng)目關(guān)于vite.config.js文件的配置方法
Vue項(xiàng)目創(chuàng)建時(shí),我們見過(guò)vue-cli 創(chuàng)建項(xiàng)目和webpack 創(chuàng)建項(xiàng)目等方式,這篇文章主要介紹了Vue+vite創(chuàng)建項(xiàng)目關(guān)于vite.config.js文件的配置方法,需要的朋友可以參考下2023-06-06
ElementPlus組件與圖標(biāo)按需自動(dòng)引入的實(shí)現(xiàn)方法
這篇文章主要介紹了ElementPlus組件與圖標(biāo)按需自動(dòng)引入的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06
Vue表單提交點(diǎn)擊事件只允許點(diǎn)擊一次的實(shí)例
這篇文章主要介紹了Vue表單提交點(diǎn)擊事件只允許點(diǎn)擊一次的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
element 結(jié)合vue 在表單驗(yàn)證時(shí)有值卻提示錯(cuò)誤的解決辦法
這篇文章主要介紹了element 結(jié)合vue 在表單驗(yàn)證下,有值卻提示錯(cuò)誤的解決辦法,需要的朋友可以參考下2018-01-01
Vue3使用時(shí)應(yīng)避免的10個(gè)錯(cuò)誤總結(jié)
Vue?3已經(jīng)穩(wěn)定了相當(dāng)長(zhǎng)一段時(shí)間了。許多代碼庫(kù)都在生產(chǎn)環(huán)境中使用它,其他人最終都將不得不遷移到Vue?3。我現(xiàn)在有機(jī)會(huì)使用它并記錄了我的錯(cuò)誤,下面這些錯(cuò)誤你可能想要避免2023-03-03
vue中使用過(guò)濾器filters的this為undefined的問題
這篇文章主要介紹了vue中使用過(guò)濾器filters的this為undefined的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

