Vuex 是 Vue.js 的官方狀態管理工具。在這篇教程中,我將解釋它的基本用法。
- Vuex 簡介
- 為什麼應該使用 Vuex
- 讓我們開始吧
- 建立 Vuex store
- 一個使用 store 的使用案例
- 介紹我們需要的新組件
- 將這些組件添加到應用程式中
- 將狀態添加到 store 中
- 添加一個 Mutation
- 添加一個 getter 來引用狀態屬性
- 將 Vuex store 添加到應用程式中
- 使用 commit 在使用者操作中更新狀態
- 使用 getter 來打印狀態值
- 總結
簡介到 Vuex
Vuex 是 Vue.js 的官方狀態管理工具。
它的工作是在應用程式的組件之間共享數據。
在 Vue.js 中,組件可以使用以下方式進行通訊:
- props,從父組件將狀態傳遞給子組件。
- events,從子組件更改父組件的狀態,或將根組件用作事件匯流排。
有時候,這些簡單的方法可能無法滿足需求。
在這種情況下,最好的選擇是將狀態集中存儲在一個單獨的 store 中。這就是 Vuex 的作用。
為什麼應該使用 Vuex
在 Vue 中,你可以使用 Vuex 之外的其他狀態管理工具(例如 Redux),但 Vuex 的主要優勢在於它是官方推薦的,並且與 Vue.js 的整合非常出色。
與 React 不同,你需要從眾多的庫中選擇一個,因為 React 生態系統龐大,並沒有一個明確的標準。最近,Redux 是最受歡迎的選擇,其次是 MobX。而在 Vue 中,我敢肯定說,你不需要尋找其他選擇,Vuex 就是最好的選擇,特別是當你剛開始時。
Vuex 借鑒了 React 生態系統的許多思想,因為它們都遵循了 Redux 引入的 Flux 模式。
如果你已經熟悉 Flux 或 Redux,那麼 Vuex 將非常容易理解。如果你不熟悉,沒有問題-我將從頭開始解釋每個概念。
Vue 應用程式中的組件可以擁有自己的狀態。例如,輸入框將在本地存儲輸入的數據。這是完全可以的,即使使用了 Vuex,組件也可以擁有本地狀態。
當你開始使用各種方法傳遞狀態時,就知道你需要像 Vuex 這樣的東西了。
在這種情況下,Vuex 提供了一個集中存儲狀態的存儲庫,並且通過要求存儲庫來改變狀態。
每個依賴於特定狀態的組件都可以使用存取器從存儲庫中獲取狀態,這將確保在該狀態發生變化時立即更新。
使用 Vuex 將使應用程式變得更為複雜,因為需要按照一定的方式設定才能正確工作,但如果能解決繁瑣的道路傳遞和事件系統所帶來的混亂,它是一個不錯的選擇。
讓我們開始吧
在這個例子中,我將從 Vue CLI 應用程式開始。Vuex 也可以通過直接將其載入到 script 標籤中來使用,但由於 Vuex 更適合於大型應用程式,所以您更有可能在結構化的應用程式中使用它,例如使用 Vue CLI 快速啟動的應用程式。
我使用的示例代碼將放在 CodeSandbox 上,CodeSandbox 是一個很棒的服務,已經準備好了一個 Vue CLI 的示例,您可以在 https://codesandbox.io/s/vue 上使用它。我建議您使用它來進行實驗。
進入 CodeSandbox 後,點擊Add dependency按鈕,輸入 “vuex” 並單擊它。
現在 Vuex 將在項目的依賴項中列出。
要在本地安裝 Vuex,您可以在項目文件夾中運行 npm install vuex
或 yarn add vuex
。
建立 Vuex store
現在我們已經準備好創建 Vuex store。
這個文件可以放在任何地方。通常建議將它放在 src/store/store.js
文件中,因此我們將這樣做。
在這個文件中,我們初始化 Vuex,並告訴 Vue 使用它:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({})
我們導出了一個 Vuex store 對象,該對象使用 Vuex.Store()
API 創建。
一個使用 store 的使用案例
現在我們有了基礎,讓我們想一個對於 Vuex 的使用案例,以便我能夠介紹它的概念。
例如,我有兩個兄弟組件,一個包含一個輸入框,另一個打印該輸入框的內容。
當輸入框改變時,我希望也更改第二個組件中的內容。非常簡單,但對於我們來說勢必適合。
介紹我們需要的新組件
我刪除 HelloWorld 組件,添加一個 Form 組件和一個 Display 組件。
<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input name="flavor">
</div>
</template>
<template>
<div>
<p>You chose ???</p>
</div>
</template>
將這些組件添加到應用程式中
我們將它們添加到 App.vue 代碼中,而不是添加到 HelloWorld 組件中:
<template>
<div id="app">
<Form/>
<Display/>
</div>
</template>
<script>
import Form from './components/Form'
import Display from './components/Display'
export default {
name: 'App',
components: {
Form,
Display
}
}
</script>
將狀態添加到 store 中
在這個基礎上,我們回到 store.js 文件,並在 store 中添加一個名為 state
的屬性,它是一個包含 flavor
屬性的對象。初始值為空字符串。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
}
})
當用戶在輸入框中輸入時,我們將更新它。
添加一個 Mutation
狀態可以使用 mutations 進行更改。我們設置了一個 mutation,在 Form 組件中使用它來通知 store 狀態應該更改。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
}
})
添加一個 getter 來引用狀態屬性
設置完成後,我們需要一種方式來查看狀態。我們使用 getters 來實現這一目的。我們為 flavor
屬性設置了一個 getter:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
flavor: ''
},
mutations: {
change(state, flavor) {
state.flavor = flavor
}
},
getters: {
flavor: state => state.flavor
}
})
請注意,getters
是一個對象,flavor
是此對象的一個屬性,它接受狀態作為參數,並返回狀態的 flavor
屬性。
將 Vuex store 添加到應用程式中
現在可以使用 store 了。回到我們的應用程式代碼中,在 main.js 文件中,我們需要導入狀態並使其在 Vue 應用程式中可用。
我們導入
import { store } from './store/store'
並將其添加到 Vue 應用程式中:
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})
一旦添加這個,由於這是主要的 Vue 組件,每個 Vue 組件中的 store
變量都將指向 Vuex store。
使用 commit 在使用者操作中更新狀態
讓我們在用戶輸入時更新狀態。
我們使用 store.commit()
API 實現這一目的。
但首先,讓我們創建一個方法,當輸入內容改變時調用該方法。我們使用 @input
而不是 @change
,因為後者只在焦點從輸入框移開時觸發,而 @input
在每個按鍵按下時都會調用。
<template>
<div>
<label for="flavor">Favorite ice cream flavor?</label>
<input @input="changed" name="flavor">
</div>
</template>
<script>
export default {
methods: {
changed: function(event) {
alert(event.target.value)
}
}
}
</script>
現在我們有了 flavor 的值,我們使用 Vuex API:
<script>
export default {
methods: {
changed: function(event) {
this.$store.commit('change', event.target.value)
}
}
}
</script>
看到我們如何使用 this.$store
引用 store 嗎?這是由於在主 Vue 組件初始化中包含了 store 對象。
commit()
方法接受一個 mutation 名稱(我們在 Vuex store 中使用了 change
),以及一個作為回調函數的第二個參數的載荷,將傳遞給該 mutation 作為第二個參數。
使用 getter 來打印狀態值
現在,我們需要在 Display 模板中引用此值的 getter,使用 $store.getters.flavor
。可以移除 this
,因為我們在模板中,而 this
是隱式的。
<template>
<div>
<p>You chose {{ $store.getters.flavor }}</p>
</div>
</template>
總結
這就是關於 Vuex 的介紹了!
完整可運行的代碼可以在 https://codesandbox.io/s/zq7k7nkzkm 找到。
這裡還有很多概念需要學習:
- actions
- modules
- helpers
- plugins
但你已經掌握了基本知識,可以在官方文檔中了解更多相關資訊。
祝你編碼愉快!