什麼是 Vuex?
Vuex 是 Vue 應用程式的狀態管理,組件常會跨結構的傳遞狀態、需要全域狀態的管理,用 Vuex 可以更容易的控管你的資料流。
沒有用Vuex
使用Vuex
Vuex 的前置作業
store/index.js
1 2 3 4 5 6 7 8
| import { createStore } from "vuex";
export default createStore({ state: {}, actions: {}, mutations: {}, modules: {}, });
|
main.js
1 2 3 4 5 6 7
| import { createApp } from "vue"; import App from "./App.vue"; import store from "./store";
createApp(App) .use(store) .mount("#app");
|
State Getters Mutations Actions
State:
🔸 存放資料狀態
Getters:
🔸 取得狀態,類似 computed 重組資料
🔸 components 不要直接取得 state,先用 getters 去處理資料邏輯,再回傳資料。
Mutations:
🔸 唯一改變 state 的方法
🔸 只能做同步操作,mutations 不能做非同步操作
🔸 mutations 需用 commit 呼叫
Actions:
🔸 actions 觸發 mutations,commit 會發送事件給 mutations
🔸 actions 才做非同步操作
🔸 需用 dispatch 呼叫
🔸 不能更改 state
流程: components ➜ dispatch ➜ actions
➜ commit ➜ mutations
➜ state
➜ getters
➜ components
Vuex 範例
側邊選單收合
App.vue
1 2 3 4 5 6 7 8 9 10 11
| import MenuBtn from "../src/components/MenuBtn.vue"; import MenuSlid from "../src/components/MenuSlid.vue"; export default { components: { MenuBtn, MenuSlid, }, setup() { return {}; }, };
|
1 2 3 4 5 6 7
| <div id="app"> <MenuBtn /> <div class="content"> <img id="img" alt="Vue logo" src="./assets/logo.png" /> </div> <MenuSlid /> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| * { padding: 0; margin: 0; box-sizing: border-box; } html, body { width: 100%; height: 100%; font-family: "Microsoft JhengHei", "Heiti TC", "sans-serif"; } #img { display: block; } #app { position: relative; width: 100%; height: 100%; > .content { width: 100%; height: 100%; background-image: url("https://source.unsplash.com/WLUHO9A_xik/1600x900"); background-size: cover; background-position: center; display: flex; justify-content: center; align-items: center; } }
|
store/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import { createStore } from "vuex";
export default createStore({ state: { isOpen: false, }, actions: { handMenuOpen(context) { const openBool = !context.state.isOpen; context.commit('handOpenState', openBool); } }, mutations: { handOpenState(state, openBool) { state.isOpen = openBool; } }, getters: { isOpen(state) { return state.isOpen; } }, });
|
MenuSlid.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { computed } from 'vue'; import { useStore } from "vuex"; export default { setup() { const store = useStore(); const isOpen = computed(()=>{ return store.getters.isOpen }) const handClickMenu = () => { store.dispatch('handMenuOpen'); }; return { handClickMenu, isOpen }; }, };
|
1 2 3 4 5 6 7 8 9 10 11
| <div :class="['menu', {open: isOpen} ]"> <a class="closeBtn" @click="handClickMenu"> <i class="fas fa-times fa-3x"></i> </a> <ul class="nav"> <li><a>abous</a></li> <li><a>content</a></li> <li><a>user</a></li> <li><a>address</a></li> </ul> </div>
|
MenuBtn.vue
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { useStore } from "vuex"; const store = useStore(); export default { setup() { const store = useStore(); const handClickMenu = () => { store.dispatch('handMenuOpen'); };
return { handClickMenu }; }, };
|
1 2 3
| <a class="menuBtn" @click="handClickMenu"> <i class="fas fa-bars fa-3x"></i> </a>
|
1 2 3 4 5 6 7 8
| a.menuBtn { cursor: pointer; position: absolute; color: #fff; z-index: 10; top: 50px; right: 50px; }
|
Vuex 結構拆分
當 Vuex 內容越來越多時,可以拆分檔案,比較好管理
store/index.js
1 2 3 4 5 6 7 8 9
| import { createStore } from "vuex"; import state from './state.js'; import actions from './actions.js'; import mutations from './mutations.js'; import getters from './getters.js';
export default createStore({ state, actions, mutations, getters });
|
store/state.js
1 2 3
| export default { isOpen: false, }
|
store/getters.js
1 2 3 4 5
| export default { isOpen(state) { return state.isOpen; } }
|
store/mutations.js
1 2 3 4 5
| export default { handOpenState(state, openBool) { state.isOpen = openBool; } }
|
store/actions.js
1 2 3 4 5 6
| export default { handMenuOpen(context) { const openBool = !context.state.isOpen; context.commit('handOpenState', openBool); } }
|
Vuex modules
module可以依照功能來區分資料
設定namespaced在不同的modules可以有一樣的名稱,依照modules名稱做判斷
store/Auth/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| export default { namespaced: true, state: { token: '', }, actions: { handSetToken(context, token) { context.commit('setToken', token); } }, mutations: { setToken(state, token) { state.token = token; } }, getters: { getToken(state) { return state.token; } } }
|
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { onMounted } from 'vue'; import { useStore } from 'vuex'; export default { setup() { const store = useStore(); onMounted(() => { store.dispatch('Auth/handSetToken', 'aaa'); console.log(store.getters['Auth/getToken']); }) return {}; }, };
|
以上是我的學習筆記,希望也有幫助到你哦 😀
🚀實體工作坊分享
最近時賦學苑開了實體體驗課,即使你對程式碼沒有概念也能上手!Lala 會帶你一起做出一個個人品牌形象網站,帶你快速了解前端的開發流程,快跟我們一起玩轉 Web 吧!
🚀線上課程分享
線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。
Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住
如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!
Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。