Vue Router Navigation Guards: Building a Protected Route
This challenge focuses on implementing route guards in a Vue.js application using TypeScript. Navigation guards are crucial for controlling access to routes, performing actions before navigation, or redirecting users based on certain conditions. You will create a simple authentication system to protect specific routes.
Problem Description
You need to build a basic authentication mechanism for a Vue application using Vue Router's navigation guards. Specifically, you will implement a beforeEach guard to check if a user is authenticated before allowing them to access a "dashboard" route. If the user is not authenticated, they should be redirected to a "login" route.
Key Requirements:
- Vue Router Setup: You should have a basic Vue Router instance configured with at least two routes:
/(home),/login, and/dashboard. - Authentication State: Simulate an authentication state. This can be a simple boolean variable or a more sophisticated object representing a user. For this challenge, a global boolean variable
isAuthenticatedwill suffice. beforeEachNavigation Guard: Implement a globalbeforeEachnavigation guard.- Route Protection: The
/dashboardroute should be protected. - Redirection Logic:
- If a user tries to navigate to
/dashboardandisAuthenticatedisfalse, they should be redirected to/login. - If a user tries to navigate to
/loginandisAuthenticatedistrue, they should be redirected to/dashboard(as they are already logged in). - All other navigation should proceed as normal.
- If a user tries to navigate to
- TypeScript: All code should be written in TypeScript.
Expected Behavior:
- Navigating to
/should work without authentication. - Navigating to
/loginwhen not authenticated should display the login page. - Navigating to
/dashboardwhen not authenticated should redirect to/login. - Navigating to
/loginwhen already authenticated should redirect to/dashboard. - Navigating to
/dashboardwhen authenticated should display the dashboard.
Edge Cases to Consider:
- What happens if the user is already on the
/loginpage and attempts to navigate to it again? (Should not cause an infinite loop). - What happens if the user is already on the
/dashboardpage and attempts to navigate to it again?
Examples
Example 1: User navigates to the protected dashboard route while unauthenticated.
// Assume isAuthenticated is false globally
// User attempts to navigate to '/dashboard'
router.push('/dashboard');
// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is false, the user is redirected to '/login'.
// The router.push('/dashboard') effectively becomes router.push('/login').
Example 2: User navigates to the login route while already authenticated.
// Assume isAuthenticated is true globally
// User attempts to navigate to '/login'
router.push('/login');
// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is true, the user is redirected to '/dashboard'.
// The router.push('/login') effectively becomes router.push('/dashboard').
Example 3: User navigates to the dashboard route while authenticated.
// Assume isAuthenticated is true globally
// User attempts to navigate to '/dashboard'
router.push('/dashboard');
// Expected Behavior:
// The beforeEach guard intercepts the navigation.
// Since isAuthenticated is true, the navigation to '/dashboard' is allowed to proceed.
Constraints
- Your solution should be implemented within a Vue.js 3 project using the Composition API and Vue Router 4.
- The simulated authentication state (
isAuthenticated) should be a simple boolean variable, managed globally or passed appropriately. - The solution should be performant and not introduce unnecessary overhead for typical navigation.
Notes
- You'll need to set up a basic Vue project and install
vue-router. - Think about how to manage the
isAuthenticatedstate. A simple global variable is sufficient for this challenge, but in a real application, you'd likely use a state management solution like Pinia or Vuex. - The
next()function inbeforeEachis crucial for controlling navigation. Remember its different argument types (boolean, string, object). - Consider how to handle the initial load of the application and its route guards.