Vue Router 與 Vuex 集成
在 Vue 3 的應用開發中,Vue Router 和 Vuex 是兩個常用的核心庫,分別負責應用的路由管理和狀態管理。當你的應用變得複雜時,將這兩個工具結合使用能夠大大提升開發效率和用戶體驗。下面我們將介紹如何將 Vue Router 和 Vuex 集成,並使用它們來管理應用的狀態和路由。
1. 為什麼要將 Vue Router 與 Vuex 集成?
當應用中有路由跳轉時,經常會需要對某些路由進行權限控制(如需要用戶登錄才能訪問),或者根據不同路由顯示不同的數據,這時就需要 Vuex 和 Vue Router 進行配合。通過將這兩者集成,能夠實現以下功能:
- 基於用戶狀態進行路由訪問控制:如登錄狀態控制、角色權限控制。
- 在路由變更時更新 Vuex 狀態:當路由改變時,Vuex 可以跟隨更新應用的狀態。
- 根據 Vuex 狀態進行條件性的路由跳轉。
2. 基礎步驟:集成 Vue Router 和 Vuex
1. 安裝 Vue Router 和 Vuex
首先,你需要確保已經安裝了 Vue Router 和 Vuex:
1
npm install vue-router@next vuex@next
2. 設置 Vuex Store 和 Vue Router
在你的項目中,分別設置 Vuex 的 store 和 Vue Router 的路由。
- Vuex Store 設置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { createStore } from 'vuex';
const store = createStore({
state: {
isAuthenticated: false, // 用於跟蹤登錄狀態
user: null
},
mutations: {
login(state, user) {
state.isAuthenticated = true;
state.user = user;
},
logout(state) {
state.isAuthenticated = false;
state.user = null;
}
}
});
export default store;
- Vue Router 設置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
import Login from './views/Login.vue';
import Dashboard from './views/Dashboard.vue';
const routes = [
{ path: '/', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/dashboard', name: 'Dashboard', component: Dashboard }
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
3. 在主應用中使用 Vuex 和 Vue Router
在 main.js
中引入 Vuex 和 Vue Router,並將它們掛載到 Vue 應用中:
1
2
3
4
5
6
7
8
9
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
import router from './router';
const app = createApp(App);
app.use(store);
app.use(router);
app.mount('#app');
這樣,你的應用已經基礎集成了 Vue Router 和 Vuex。
3. 基於 Vuex 狀態進行路由控制
1. 路由守衛控制訪問權限
可以使用 Vue Router 的 全局導航守衛(navigation guards)來控制哪些路由需要登錄才能訪問,並根據 Vuex 中的 isAuthenticated
狀態來進行跳轉控制。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
router.beforeEach((to, from, next) => {
const isAuthenticated = store.state.isAuthenticated;
// 檢查目標路由是否需要認證
if (to.name === 'Dashboard' && !isAuthenticated) {
// 如果未認證,則跳轉到登錄頁面
next({ name: 'Login' });
} else {
// 如果已認證,則繼續導航
next();
}
});
在這裡,我們使用 router.beforeEach()
全局守衛,對於某些需要登錄的頁面(如 Dashboard
),如果用戶未登錄(即 isAuthenticated
為 false
),則重定向到登錄頁面。
2. 登錄後重定向
在登錄操作完成後,我們可以更新 Vuex 的狀態,並將用戶重定向到之前嘗試訪問的受保護路由,這樣可以提供更加流暢的用戶體驗。
範例:
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
<template>
<div>
<form @submit.prevent="login">
<input type="text" v-model="username" placeholder="用戶名" />
<button type="submit">登錄</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
username: ''
};
},
methods: {
login() {
// 模擬登錄成功
this.$store.commit('login', this.username);
// 重定向到之前嘗試訪問的頁面,默認重定向到 Dashboard
const redirect = this.$route.query.redirect || '/dashboard';
this.$router.push(redirect);
}
}
};
</script>
登錄成功後,我們通過 this.$store.commit('login')
更新 Vuex 狀態,並通過 this.$router.push()
將用戶重定向到他們原本想訪問的頁面。
4. 根據 Vuex 狀態更新 UI 和跳轉
1. 根據 Vuex 狀態控制 UI
根據 Vuex 狀態來動態顯示不同的導航鏈接或按鈕,例如登錄和登出按鈕。
範例:
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
30
31
32
33
<template>
<nav>
<ul>
<li><router-link to="/">Home</router-link></li>
<li v-if="!isAuthenticated"><router-link to="/login">Login</router-link></li>
<li v-if="isAuthenticated"><router-link to="/dashboard">Dashboard</router-link></li>
<li v-if="isAuthenticated"><button @click="logout">Logout</button></li>
</ul>
</nav>
</template>
<script>
import { computed } from 'vue';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const isAuthenticated = computed(() => store.state.isAuthenticated);
const logout = () => {
store.commit('logout');
// 登出後返回首頁
store.$router.push('/');
};
return {
isAuthenticated,
logout
};
}
};
</script>
這裡,我們根據 isAuthenticated
狀態動態顯示登錄和登出按鈕,並在用戶登出時,將其重定向到首頁。
2. 根據 Vuex 狀態跳轉
有時候需要根據 Vuex 的狀態自動跳轉到某個頁面。例如,當用戶已登錄,進入登錄頁面時自動重定向到儀表板頁面。
範例:
1
2
3
4
5
6
7
8
9
10
router.beforeEach((to, from, next) => {
const isAuthenticated = store.state.isAuthenticated;
// 如果用戶已登錄並且嘗試訪問登錄頁面,則重定向到儀表板
if (to.name === 'Login' && isAuthenticated) {
next({ name: 'Dashboard' });
} else {
next();
}
});
這樣的路由守衛可以避免已登錄用戶再次進入登錄頁面,提供更好的用戶體驗。
5. 總結
將 Vue Router 與 Vuex 集成,可以幫助你更好地控制路由訪問權限和狀態管理,實現如下功能:
- 使用 Vuex 管理應用的登錄狀態和用戶信息。
- 使用 Vue Router 的導航守衛來控制訪問權限,確保用戶只有在登錄後才能訪問某些頁面。
- 根據 Vuex 狀態動態更新 UI 和進行路由跳轉。
- 使用 Vuex 和 Vue Router 組合實現更好的用戶登錄和登出體驗。
這種結合方式在處理大型應用時尤為有效,讓開發過程更加簡潔、有條理。