Vuex 是 Vue.js 官方的狀態管理庫。它是一個讓你能在應用中集中管理共享狀態的工具。當應用的規模逐漸增大,組件之間的數據傳遞變得越來越復雜時,Vuex 就成為了救星,提供了一個集中式的存儲來管理所有的組件狀態,并且保證狀態以一種可預測的方式發生變化。
文章目錄
- 目的
- Vuex 怎么做的?
- (1). State
- <1> 為什么有 `data` 和 `state`?
- `data` 關心的是單個組件的內部狀態;
- <2> 使用數據信息
- (2)Getters
- (3)Mutations
- Vuex 嚴格模式
- (4) Actions
- (5)Modules
- Vuex 的“心臟” —— 單向數據流
- 為什么 Vuex 很“牛”?
- 總結:Vuex 讓你理清數據的“廚房”!
目的
Vuex 的目標是讓你的 Vue 應用在狀態管理上不至于像一鍋亂燉,避免在多個組件間傳遞數據時亂七八糟。你可以想象,在 Vuex 中,所有狀態都被“規范化”了,組件們可以優雅地共享這些數據,而不需要通過層層的父子傳遞 props 和事件。這也解決了“數據共享時,父組件、子組件、孫組件之間的數據流動混亂”的老大難問題。
- 集中式管理:把所有共享的狀態存放在一個地方,統一管理,避免數據凌亂。
- 嚴格的單向數據流:讓數據更新的過程清晰可控,不會出現“你修改我,我改你”的尷尬局面。
- 跨組件通信:組件之間不再需要通過復雜的 prop 和 event 來傳遞數據,只需要從 store 獲取就好。
Vuex 怎么做的?
Vuex 采用了幾個核心概念來實現這一切:State、Getters、Mutations、Actions 和 Modules。
(1). State
-
state
是存儲數據的地方,它是 Vuex 的數據源。在應用中,組件需要共享的狀態應該放在state
中。你可以將它看作 Vuex 提供的“全球變量”,它能夠幫助你在組件間共享數據。 -
當然,如果你把所有東西都放進 state,那可能會導致一堆“雜貨”,所以一定要有一定的規劃,避免所有數據都成堆的亂象。 (′ω`)
const store = new Vuex.Store({state: {count: 0}
})
<1> 為什么有 data
和 state
?
-
data
是用來管理組件自身的狀態,關注的是單一組件內的數據變化; -
state
是 Vuex 用來管理全局狀態的地方,目的是讓多個組件能夠共享和操作相同的數據。
換句話說:
特性 | data | state |
---|---|---|
作用范圍 | 僅限于當前組件的局部狀態 | 全局狀態,多個組件共享 |
存儲位置 | Vue 組件內部 | Vuex store(狀態管理倉庫) |
訪問方式 | this.count | this.$store.state.count |
響應性 | 自動響應式更新視圖 | 自動響應式更新視圖 |
用途 | 處理單個組件的狀態,通常是 UI 數據 | 處理跨組件共享的狀態 |
舉個例子,如果你有一個購物車應用,在每個商品詳情頁面,商品的數量和價格會保存在該組件的 data
中;而購物車總數、用戶登錄狀態、支付信息等會保存在 Vuex 的 state
中,讓不同組件都能訪問和修改。
所以,data
和 state
是兩個不同范圍的狀態管理工具,一個是組件級的局部狀態管理,一個是全局級的狀態管理。
<2> 使用數據信息
-
任何組件都可以通過
this.$store.state
來訪問 Vuex 中的state
。// Vuex store const store = new Vuex.Store({state: {count: 0},mutations: {increment(state) {state.count++;}} });// 組件中訪問 state export default {computed: {// 直接通過 this.$store.state 訪問 state 中的數據count() {return this.$store.state.count;}},methods: {increment() {// 通過 mutation 更新 statethis.$store.commit('increment');}} }
-
通過輔助函數mapState訪問
state
數據import { mapState } from 'vuex';export default {computed: {// 使用 mapState 輔助函數...mapState({count: state => state.count // 將 state.count 映射到組件的 computed 屬性中})},methods: {increment() {this.$store.commit('increment');}} }
(2)Getters
getters
是從state
中派生出一些狀態的“函數”,類似于 Vue 的計算屬性,它們不會直接改變state
,而是返回一些加工過的計算結果。- 例如,如果
state
中有一個列表,我們可以在getters
中處理這些數據,像是過濾出有效的元素或者計算某個值。
const store = new Vuex.Store({state: {count: 0},getters: {doubleCount: state => state.count * 2}
})
Getters 可不只是“取拿冰箱里的食材”,還會根據你的需求“做點小加工”,像做飯前的切菜一樣(如果你能忍受長時間等待的切菜過程…)。
(3)Mutations
Mutations
就是唯一合法的修改state
的唯一途徑!它們是同步的,你不能在這里做異步操作(想抄捷徑?做夢去吧)。每次要改變 state 的內容,你都必須通過 mutation 來“正式授權”進行修改。
const store = new Vuex.Store({state: {count: 0},mutations: {increment(state) {state.count++}}
})
Mutations 就像一個“廚房的管理員”,它是唯一能決定“今天菜單”是什么的,不通過它你就不能隨便動手。想做什么就要跟它打招呼!
-
例如,你可能會寫一個 mutation 來修改用戶的登錄狀態:
mutations: {login(state) {state.loggedIn = true;} }
Vuex 嚴格模式
要啟用 Vuex 的嚴格模式,只需要在創建 Vuex.Store
實例時,將 strict
屬性設置為 true
即可。
const store = new Vuex.Store({strict: true, // 啟用嚴格模式
});
- 允許通過
mutations
修改state
:如果你按照 Vuex 的規范通過commit
調用mutations
來修改state
,Vuex 嚴格模式不會報錯。 - 不允許直接修改
state
:如果你在 Vue 組件或其他地方直接修改state
,嚴格模式會報錯,并且提供警告。比如:
this.$store.state.count++; // 這是不被允許的,嚴格模式下會觸發警告
Vuex 在開發環境下會檢測到這種不合規的操作,并提示錯誤信息。
(4) Actions
-
actions
類似于mutations
,但它們可以包含異步操作。actions
用來派發 mutation,通常你會在actions
中執行一些異步操作(比如向后端發送請求),然后通過commit
來觸發 mutation。actions: {async fetchData({ commit }) {const data = await axios.get('/api/data');commit('setData', data);} }
-
它們可以像一個小助手一樣,幫你完成一些復雜的異步任務(比如 API 請求),最后將結果交給 mutation 來更新狀態。
const store = new Vuex.Store({state: {count: 0},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment')}, 1000)}}
})
它們可以像一個小助手一樣,幫你完成一些復雜的異步任務(比如 API 請求),最后將結果交給 mutation 來更新狀態。
(5)Modules
- Vuex 還支持將 store 分成多個模塊,每個模塊都有自己的 state、mutations、actions 和 getters。這對于大型應用來說非常有用,它能幫助你將不同的業務邏輯進行分離。
- 例如,如果你有一個用戶模塊和一個商品模塊,你可以將它們分別定義在不同的模塊中,避免了一個大的
store
變得過于復雜。 - 看起來很像分區管理,有了這個功能,你就可以把代碼管理得像一個井然有序的圖書館,而不是一團亂麻(?_?)。
const store = new Vuex.Store({modules: {moduleA: {state: { count: 0 },mutations: {increment(state) {state.count++}}}}
})
Modules 就是讓你可以分攤廚房的責任,讓多個廚師各司其職,避免一鍋煮成了亂燉(不同模塊管理自己的狀態,既不沖突又井然有序)。
Vuex 的“心臟” —— 單向數據流
Vuex 強調了單向數據流(state -> getter -> component -> actions -> mutation -> state),你可以把它看作是一個規范化的流水線,每一步都非常清晰:
- state 提供數據;
- getter 提供處理過的數據;
- component 用來展示數據;
- actions 負責異步操作;
- mutation 最終改變數據。
整個流程都遵循著嚴格的規則,數據像流水一樣流動。想要逆流而上?想都別想(除非是調皮的 mutation…)。
為什么 Vuex 很“牛”?
Vuex 是一個非常嚴謹的庫,它的設計理念非常高大上(可能是你不想用它時最喜歡說的句子)。它讓你避免了在組件間“亂搞”數據的尷尬局面,確保了每個數據變動都有清晰的路徑和軌跡。
Vuex 的優點包括:
- 集中管理狀態:所有的狀態都集中在 store,方便管理。
- 嚴格的數據流控制:單向數據流讓數據變化有跡可循。
- 便捷的調試工具:Vuex 提供的時間旅行調試功能讓你隨時了解數據如何變化。
- 模塊化管理:即使是龐大的應用,也能清晰拆分和管理。
但如果你是小型應用,Vuex 的使用就有點像“用大炮打蚊子”。你可能會覺得:這怎么像是拿高科技武器去捉小貓咪呢?(不過一旦應用擴展,你會發現 Vuex 的威力)。
總結:Vuex 讓你理清數據的“廚房”!
Vuex 是一個強大的工具,它讓 Vue 應用的狀態管理變得更加清晰和可預測。在大型應用中,Vuex 能夠有效地集中管理狀態,避免了直接操作 DOM 元素的凌亂(畢竟,Vuex 和 DOM 元素并沒有什么關系哦~(。??︿??。))。
當然,如果你是開發一個小型應用,Vuex 可能就有點“重”。不過沒關系,就像你不需要開動整個火車來送一包米那樣,小應用用別的狀態管理方法就夠了。所以,Vuex 不適合“短跑”,但適合長期合作!(如果你不怕它有時“拗口”…)