Параметры маршрута и переходы
У каждой статьи блога своя страница: /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" /> — тогда компонент пересоздастся при каждом новом адресе.