Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Параметры маршрута и переходы

У каждой статьи блога своя страница: /posts/1, /posts/2 и так далее. Заводить маршрут на каждую статью невозможно, поэтому в адресе объявляют параметр — изменяемую часть, которая начинается с двоеточия. Компонент читает её и загружает нужную статью.

Маршрут с параметром

Добавьте маршрут в src/router/index.js:

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
import PostView from '../views/PostView.vue'
 
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    { path: '/', name: 'home', component: HomeView },
    { path: '/about', name: 'about', component: AboutView },
    { path: '/posts/:id', name: 'post', component: PostView },
  ],
})
 
export default router

Адрес /posts/7 подойдёт под этот маршрут, и параметр id получит значение '7' — всегда строку.

Чтение параметра

Создайте src/views/PostView.vue. Текущий маршрут возвращает функция useRoute:

<!-- src/views/PostView.vue -->
<script setup>
import { useRoute } from 'vue-router'
import { useFetch } from '../composables/useFetch.js'
 
const route = useRoute()
const { data: post, loading, error } = useFetch(
  `https://jsonplaceholder.typicode.com/posts/${route.params.id}`,
)
</script>
 
<template>
  <p v-if="loading">Загрузка...</p>
  <p v-else-if="error">Статья не найдена.</p>
  <article v-else>
    <h1>{{ post.title }}</h1>
    <p>{{ post.body }}</p>
  </article>
</template>

Откройте http://localhost:5173/posts/1 — появятся заголовок и текст первой статьи. Композабл useFetch — из урока про загрузку данных.

Ссылки на статьи

В src/components/PostList.vue превратите заголовки в ссылки:

<!-- src/components/PostList.vue, фрагмент шаблона -->
<li v-for="post in posts" :key="post.id">
  <RouterLink :to="{ name: 'post', params: { id: post.id } }">
    {{ post.title }}
  </RouterLink>
</li>

Клик по заголовку на главной открывает страницу статьи. Можно писать и строкой: :to="'/posts/' + post.id", но ссылка по имени не зависит от формата адреса.

Переход из кода

Иногда переходить нужно не по клику на ссылку, а после действия — например, вернуться к списку. Для этого есть useRouter:

<script setup>
import { useRouter } from 'vue-router'
 
const router = useRouter()
 
function goHome() {
  router.push({ name: 'home' })
}
</script>
 
<template>
  <button @click="goHome">К списку статей</button>
</template>

Кнопка откроет главную страницу.

ВызовЧто делает
router.push(...)Переход с новой записью в истории
router.replace(...)Переход с заменой текущей записи
router.back()Шаг назад, как кнопка браузера

Параметры запроса

Часть адреса после ? доступна в route.query: для /posts?page=2 значение route.query.page равно '2'.

Частая ошибка

Перейти со статьи /posts/1 на /posts/2 по ссылке «Следующая статья» и увидеть старый текст. Роутер не пересоздаёт компонент, если меняется только параметр, — PostView остаётся тем же, и загрузка в нём не повторяется. Следите за параметром через watch(() => route.params.id, ...) и загружайте статью заново или добавьте в App.vue ключ: <RouterView :key="$route.fullPath" /> — тогда компонент пересоздастся при каждом новом адресе.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.