Vuex (狀態管理模式)
概述
Vuex 是 Vue.js 官方提供的狀態管理模式(state management pattern)與函式庫,用來在 Vue 應用中集中管理多個元件共享的資料(state)。
當小型應用只有幾個元件時,父子元件之間用 props 和 $emit
傳資料已經足夠。但當應用變大、元件變多,資料需跨元件甚至跨層級傳遞時,就會變得複雜又難以維護。
這時 Vuex 就能派上用場:
它提供一個「全域的資料儲存區(store)」,讓所有元件都能讀取與更新同一份資料。
核心概念
| 名稱 |
說明 |
state |
存放資料的地方(類似資料庫) |
getters |
類似 computed,用來取得經過處理的 state |
mutations |
用來同步地修改 state 的方法 |
actions |
用來處理非同步流程,然後呼叫 mutations |
modules |
當 store 太大時可拆成模組 |
安裝與設定
安裝
建立主 store:store/index.js
在 app.js 註冊 store
資料夾結構建議
模組化範例
modules/articles.js
modules/users.js
store/index.js 匯入模組
元件中使用模組資料
使用順序與觀念整理
典型流程:
- 使用
store.dispatch('模組名稱/action') 呼叫 action(可處理非同步)
- action 中呼叫
commit('mutation') 修改資料
- 元件透過
store.state 或 computed() 取得資料顯示畫面
呼叫時機:
onMounted():元件初始化時抓資料
watch():變數變化時觸發
- 點擊事件:例如按下「重新整理」
搭配 async/await:
命名空間與使用方式說明
| 項目 |
說明 |
namespaced: true |
為模組啟用命名空間,呼叫 action/mutation/getter 時需加上模組名 |
modules |
將各模組匯入並註冊於主 store 中 |
| 使用方式 |
store.state.模組名.key、store.dispatch('模組名/method')、store.getters['模組名/getter']
|
官方文件參考
Vuex (狀態管理模式)
概述
Vuex 是 Vue.js 官方提供的狀態管理模式(state management pattern)與函式庫,用來在 Vue 應用中集中管理多個元件共享的資料(state)。
當小型應用只有幾個元件時,父子元件之間用
props和$emit傳資料已經足夠。但當應用變大、元件變多,資料需跨元件甚至跨層級傳遞時,就會變得複雜又難以維護。這時 Vuex 就能派上用場:
它提供一個「全域的資料儲存區(store)」,讓所有元件都能讀取與更新同一份資料。
核心概念
stategetterscomputed,用來取得經過處理的statemutationsstate的方法actionsmutationsmodules安裝與設定
安裝
# Vuex 4 支援 Vue 3,Vuex 3 用於 Vue 2 npm install vuex@4建立主 store:
store/index.js// resources/src/store/index.js import { createStore } from 'vuex'; const store = createStore({ state: { user: null, }, mutations: { setUser(state, payload) { state.user = payload; }, }, actions: { fetchUser({ commit }) { // 模擬從 API 抓資料 const user = { name: 'Jack', role: 'engineer' }; commit('setUser', user); }, }, getters: { isLoggedIn: (state) => !!state.user, } }); export default store;在
app.js註冊 storeimport store from './store'; // 引入 Vuex store createApp(App) .use(router) .use(store) // 註冊 Vuex .mount('#app');資料夾結構建議
store/ ├── index.js # 主 store ├── modules/ │ ├── articles.js # 文章模組 │ └── users.js # 使用者模組模組化範例
modules/articles.js// store/modules/articles.js export default { namespaced: true, state: () => ({ list: [], }), mutations: { setArticles(state, articles) { state.list = articles; }, }, actions: { fetchArticles({ commit }) { // 模擬 API 呼叫 const data = [ { id: 1, title: 'Vue 3 教學' }, { id: 2, title: 'Laravel 與 Vue 整合' } ]; commit('setArticles', data); }, }, getters: { articleCount: (state) => state.list.length, } };modules/users.js// store/modules/users.js export default { namespaced: true, state: () => ({ currentUser: null, }), mutations: { setUser(state, user) { state.currentUser = user; }, }, actions: { fetchUser({ commit }) { // 模擬 API const user = { id: 1, name: 'Jack' }; commit('setUser', user); }, }, getters: { isLoggedIn: (state) => !!state.currentUser, } };store/index.js匯入模組// store/index.js import { createStore } from 'vuex'; import articles from './modules/articles.js'; import users from './modules/users.js'; export default createStore({ modules: { articles, users, } });元件中使用模組資料
<script setup> import { useStore } from 'vuex'; import { onMounted, computed } from 'vue'; const store = useStore(); onMounted(() => { store.dispatch('articles/fetchArticles'); // 使用模組名稱 prefix store.dispatch('users/fetchUser'); }); const articles = computed(() => store.state.articles.list); const user = computed(() => store.state.users.currentUser); </script> <template> <div> <h2>文章列表</h2> <ul> <li v-for="a in articles" :key="a.id">{{ a.title }}</li> </ul> <h2>登入使用者</h2> <p>{{ user?.name }}</p> </div> </template>使用順序與觀念整理
典型流程:
store.dispatch('模組名稱/action')呼叫 action(可處理非同步)commit('mutation')修改資料store.state或computed()取得資料顯示畫面呼叫時機:
onMounted():元件初始化時抓資料watch():變數變化時觸發搭配 async/await:
await store.dispatch('users/fetchUser'); console.log('會員資料已更新');命名空間與使用方式說明
namespaced: truemodulesstore.state.模組名.key、store.dispatch('模組名/method')、store.getters['模組名/getter']官方文件參考
Vuex 官方文件(Vuex 4):
https://next.vuex.vuejs.org/
Vuex 命名空間說明:
https://next.vuex.vuejs.org/guide/modules.html#namespacing