Skip to content

Guide to Setting Up Vue Router in a Vue 3 Application (Part 1)

In this guide, we'll explore how to set up Vue Router in a Vue 3 application using VitePress. We'll start from an existing Vue app and incrementally add routing features. This first part covers the basics, including setup, basic route configuration, dynamic routing, and programmatic navigation. We'll provide in-depth explanations, code examples with file paths, and highlight important tips and pitfalls.

What is Vue Router

Vue Router is the official router for Vue.js, seamlessly integrating with Vue core to build Single Page Applications (SPAs). It allows you to:

  • Map URLs to components.
  • Navigate between pages without full page reloads.
  • Utilize dynamic route matching.
  • Implement nested and named views.
  • Control navigation programmatically.

Setting Up Vue Router

Step 1: Install Vue Router

Navigate to your project directory:

bash
cd my-vue-app

Install Vue Router version 4 (compatible with Vue 3):

bash
npm install vue-router@4
bash
yarn add vue-router@4

Step 2: Create Router Configuration

Create a new router directory inside src:

bash
mkdir src/router

Create an index.ts file inside the router directory:

bash
touch src/router/index.ts
src/router/index.ts
ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

Why use createWebHistory?

createWebHistory utilizes the HTML5 History API for cleaner URLs without the hash (#). It's preferred for modern web applications with proper server configurations.

Basic Route Setup

Step 3: Update main.ts

Import and use the router in your main application file.

src/main.ts
ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App).use(router).mount('#app');

Step 4: Update App.vue

Ensure your app renders the router's matched components.

src/App.vue
vue
<template>
  <div id="app">
    <nav>
      <RouterLink to="/">Home</RouterLink>
      |
      <RouterLink to="/about">About</RouterLink>
    </nav>
    <RouterView />
  </div>
</template>

<script setup>
// No script needed for now
</script>

<style>
/* Global styles */
</style>

Using <RouterLink> and <RouterView>

  • <RouterLink>: Component that renders a link to a specified route.
  • <RouterView>: Component that renders the matched component for the route.

Dynamic Routing

Step 5: Create Views

Create Home.vue and About.vue in the views directory.

bash
mkdir src/views
touch src/views/Home.vue
touch src/views/About.vue
src/views/Home.vue
vue
<template>
  <div>
    <h1>Home Page</h1>
    <p>Welcome to our movie app!</p>
    <h2>Popular Movies</h2>
    <ul>
      <li v-for="movie in movies" :key="movie.id">
        <RouterLink :to="`/movie/${movie.id}`">{{ movie.title }}</RouterLink>
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const movies = ref([
  { id: 1, title: 'Inception' },
  { id: 2, title: 'The Matrix' },
  { id: 3, title: 'Interstellar' },
]);
</script>
src/views/About.vue
vue
<template>
  <div>
    <h1>About Page</h1>
    <p>This is a sample movie application built with Vue 3 and Vue Router.</p>
  </div>
</template>

<script setup>
// No script needed for now
</script>

Step 6: Add Dynamic Route for Movie Details

Update your router configuration to include a dynamic route for movie details.

src/router/index.ts
ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import MovieDetail from '../views/MovieDetail.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
  {
    path: '/movie/:id',
    name: 'MovieDetail',
    component: MovieDetail,
    props: true,
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

Create the MovieDetail.vue component.

src/views/MovieDetail.vue
vue
<template>
  <div>
    <h1>{{ movie.title }}</h1>
    <p>{{ movie.description }}</p>
    <RouterLink to="/">Back to Home</RouterLink>
  </div>
</template>

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

const route = useRoute();
const movieId = route.params.id;

const movies = [
  { id: '1', title: 'Inception', description: 'A mind-bending thriller.' },
  { id: '2', title: 'The Matrix', description: 'A cyberpunk classic.' },
  { id: '3', title: 'Interstellar', description: 'A journey through space and time.' },
];

const movie = computed(() => movies.find((m) => m.id === movieId));

if (!movie.value) {
  // Handle movie not found
}
</script>

Pitfall: Type Mismatch

Ensure that movieId and the id in your movies array are of the same type (string or number). JavaScript may not match '1' with 1.

Programmatic Navigation

Step 7: Navigate Programmatically

You can navigate to routes programmatically using the useRouter hook.

src/components/NavigateButton.vue
vue
<template>
  <button @click="goToRandomMovie">Go to Random Movie</button>
</template>

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

const router = useRouter();

function goToRandomMovie() {
  const randomId = Math.floor(Math.random() * 3) + 1;
  router.push({ name: 'MovieDetail', params: { id: randomId.toString() } });
}
</script>

Include this component in your Home.vue:

src/views/Home.vue
vue
<template>
  <div>
    <!-- Existing content -->
    <h1>Home Page</h1>
    <p>Welcome to our movie app!</p>
    <h2>Popular Movies</h2>
    <ul>
      <li v-for="movie in movies" :key="movie.id">
        <RouterLink :to="`/movie/${movie.id}`">{{ movie.title }}</RouterLink>
      </li>
    </ul>

    <!-- Add the NavigateButton component -->
    <NavigateButton />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import NavigateButton from '../components/NavigateButton.vue';

const movies = ref([
  { id: 1, title: 'Inception' },
  { id: 2, title: 'The Matrix' },
  { id: 3, title: 'Interstellar' },
]);
</script>

When to Use Programmatic Navigation

Use programmatic navigation when navigation is triggered by events other than direct user interaction with a link, such as after form submission or a button click.

Conclusion

By following this guide, you've:

  • Installed and configured Vue Router in your Vue 3 application.
  • Set up basic routes and navigated using <RouterLink> and <RouterView>.
  • Implemented dynamic routing to display movie details.
  • Learned how to navigate programmatically within your app.

Next Steps: In the second part of this guide, we'll delve into more advanced features like nested routes, route guards, lazy loading, and more.


Happy Coding! If you have any questions or need further clarification, feel free to ask.