Implementing Hash Mode Routing in Vue.js with TypeScript
This challenge focuses on building a basic hash-based router within a Vue.js application using TypeScript. Hash mode routing allows navigation without requiring server-side support for routing, relying instead on the URL's hash fragment (e.g., /#/about). This is particularly useful for single-page applications (SPAs) deployed on static servers.
Problem Description
You are tasked with creating a simple hash router for a Vue.js application. The router should listen for changes in the URL's hash fragment, and based on the hash, render the appropriate component. The router should manage a set of routes, where each route maps a hash fragment (e.g., /about) to a component. The router should also handle navigation by updating the hash fragment and rendering the corresponding component.
Key Requirements:
- Route Mapping: Define a data structure (e.g., an object or array) to store the mapping between hash fragments and Vue components.
- Hash Listener: Implement a mechanism to listen for changes in the URL's hash fragment. This can be achieved using
window.addEventListener('hashchange', ...)orwindow.location.hash. - Component Rendering: Based on the current hash fragment, render the corresponding Vue component.
- Navigation: Provide a way to navigate to different routes by updating the hash fragment.
- Initial Route: Handle the initial hash fragment when the application loads.
- Error Handling: If the hash fragment doesn't match any defined route, display an error component (e.g., a "404 Not Found" component).
Expected Behavior:
- When the application loads, the router should render the component associated with the initial hash fragment (or a default component if the hash is empty).
- When the hash fragment changes (either through user interaction or programmatic navigation), the router should update the displayed component accordingly.
- If the hash fragment doesn't match any defined route, the router should display the error component.
- Navigation should be seamless and responsive.
Edge Cases to Consider:
- Empty hash fragment (
#) should map to a default route (e.g., a home page). - Invalid hash fragments (e.g., those containing spaces or special characters) should be handled gracefully, ideally by displaying the error component.
- The router should be able to handle multiple routes.
- Consider how to handle route parameters (though this is not a primary requirement for this basic implementation).
Examples
Example 1:
Input:
routes = {
'/': Home.vue,
'/about': About.vue,
'/contact': Contact.vue
}
Initial URL: http://localhost:8080/#/about
Output:
Renders the About.vue component.
Example 2:
Input:
routes = {
'/': Home.vue,
'/about': About.vue
}
Initial URL: http://localhost:8080/#/nonexistent
Output:
Renders the Error component (404 Not Found).
Example 3:
Input:
routes = {
'/': Home.vue
}
Initial URL: http://localhost:8080/
Output:
Renders the Home.vue component.
Constraints
- Component Type: The components in the
routesmapping should be valid Vue components (instances or constructor functions). - Hash Fragment Format: Hash fragments should start with a
/and can contain alphanumeric characters and hyphens. - Performance: The router should be efficient and avoid unnecessary re-renders. While not a primary focus, avoid excessive DOM manipulations.
- Vue Version: Assume Vue 3.
Notes
- You can use Vue's
defineComponentto define your components. - Consider using a reactive variable to store the current route, which can trigger re-renders when the hash changes.
- This is a simplified implementation; a production-ready router would include features like route parameters, navigation guards, and more robust error handling.
- Focus on the core functionality of listening for hash changes and rendering the appropriate component. Don't overcomplicate the solution.
- You are free to use any Vue 3 features you deem appropriate.
- The error component should be a simple Vue component that displays a "404 Not Found" message.