Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

Vuex 資料流,設定Vuex與modules管理

什麼是 Vuex?

Vuex 是 Vue 應用程式的狀態管理,組件常會跨結構的傳遞狀態、需要全域狀態的管理,用 Vuex 可以更容易的控管你的資料流。

沒有用Vuex
Imgur

使用Vuex
Imgur

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) // 使用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 ➜ mutationsstategetters ➜ 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觸發mutations,commit會發送事件給mutations
actions: {
handMenuOpen(context) {
// context.state等於store的state
const openBool = !context.state.isOpen;
// 傳入openBool參數給mutations
context.commit('handOpenState', openBool);
}
},
// 只有mutations可以修改state
mutations: {
// 接收actions給的參數openBool,再去改變state的值
handOpenState(state, openBool) {
state.isOpen = openBool;
}
},
// 類似computed重組資料,不要直接取得state,先用getters去處理資料邏輯,再回傳資料
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"; // 所有跟vuex有關的內容
export default {
setup() {
const store = useStore();
// 用computed取得isOpen資料,不要把整個store return出來
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();
// 用dispatch觸發一個事件到actions
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(() => {
// 因為設定namespaced,前面要加modules名稱Auth/
store.dispatch('Auth/handSetToken', 'aaa');
console.log(store.getters['Auth/getToken']);
})
return {};
},
};

以上是我的學習筆記,希望也有幫助到你哦 😀



Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️