Hone logo
Hone
Problems

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', ...) or window.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:

  1. 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).
  2. When the hash fragment changes (either through user interaction or programmatic navigation), the router should update the displayed component accordingly.
  3. If the hash fragment doesn't match any defined route, the router should display the error component.
  4. 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 routes mapping 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 defineComponent to 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.
Loading editor...
typescript