Hone logo
Hone
Problems

Enhance Vue Router with Route Meta Fields

This challenge focuses on extending the functionality of Vue Router by adding custom meta information to routes. This is a common and powerful pattern for managing route-specific data, such as authentication requirements, breadcrumb titles, or page layout configurations.

Problem Description

Your task is to implement a feature that allows defining and accessing custom meta properties within your Vue Router configuration. This meta information should be accessible within your Vue components, enabling dynamic behavior based on the current route.

What needs to be achieved:

  1. Define Meta Fields: Be able to define arbitrary meta objects for individual routes in your Vue Router configuration.
  2. Access Meta Fields: Retrieve and use these meta fields within a Vue component to influence its rendering or logic.

Key Requirements:

  • The solution must use Vue 3 with the Composition API.
  • The solution must use TypeScript for type safety.
  • You will need to configure Vue Router with routes that include custom meta properties.
  • You will need to create a Vue component that can dynamically access and display information from the current route's meta object.

Expected Behavior:

When navigating to a route that has a meta field (e.g., meta.requiresAuth or meta.pageTitle), a Vue component associated with that route should be able to read this value and act accordingly. For instance, it could conditionally display a "Login" button if requiresAuth is true, or set the document title based on pageTitle.

Important Edge Cases:

  • Routes that do not have a meta object defined.
  • Routes that have a meta object but lack specific expected fields (e.g., pageTitle is missing).

Examples

Example 1: Basic Meta Field Usage

Vue Router Configuration (Simplified):

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    component: HomeView, // Assume HomeView is a defined component
    meta: {
      pageTitle: 'Welcome to Our App',
    },
  },
  {
    path: '/dashboard',
    name: 'dashboard',
    component: DashboardView, // Assume DashboardView is a defined component
    meta: {
      pageTitle: 'User Dashboard',
      requiresAuth: true,
    },
  },
];

Vue Component (Simplified DashboardView.vue):

<template>
  <div>
    <h1>{{ pageTitle }}</h1>
    <p v-if="requiresAuth">Welcome back, user!</p>
    <p v-else>Please log in to view your dashboard.</p>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

const pageTitle = computed(() => route.meta.pageTitle as string || 'Default Title');
const requiresAuth = computed(() => route.meta.requiresAuth as boolean || false);
</script>

Input: Navigating to /dashboard.

Output: The DashboardView component will render <h1>User Dashboard</h1> and display "Welcome back, user!".

Explanation: The useRoute() hook provides access to the current route object. route.meta contains the meta object defined in the router configuration. Type assertions (as string, as boolean) and default values are used to handle cases where meta fields might be missing.

Example 2: Handling Missing Meta Fields

Vue Router Configuration (Simplified):

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
    meta: {
      pageTitle: 'Welcome',
    },
  },
  {
    path: '/about',
    name: 'about',
    component: AboutView, // Assume AboutView is a defined component
    // No meta defined for this route
  },
];

Vue Component (Simplified AboutView.vue):

<template>
  <div>
    <h1>{{ pageTitle }}</h1>
    <p>This is the about page.</p>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

// Use a default value if meta or pageTitle is missing
const pageTitle = computed(() => (route.meta.pageTitle as string) || 'About Us');
</script>

Input: Navigating to /about.

Output: The AboutView component will render <h1>About Us</h1>.

Explanation: Since the /about route has no meta object defined, route.meta will be an empty object or undefined. The computed property gracefully handles this by providing a default value for pageTitle.

Constraints

  • Vue version: 3.x
  • TypeScript version: 4.x or higher
  • Vue Router version: 4.x
  • Your solution should be a single, self-contained Vue component and its corresponding router configuration.

Notes

  • Consider how you can best type your meta object to ensure type safety when accessing its properties. You might need to extend the RouteMeta interface provided by Vue Router.
  • Think about how you would implement navigation guards (e.g., beforeEach) that use these meta fields to perform actions like redirecting unauthenticated users. While not explicitly required for this challenge, it's a natural extension.
  • The goal is to demonstrate the fundamental ability to define and access meta data.
Loading editor...
typescript