В современных веб-приложениях заголовки страниц играют важную роль для удобства пользователя и SEO. В Vue Router существует несколько подходов для динамического изменения заголовка страницы при навигации между маршрутами.
Vue Router позволяет добавлять произвольные метаданные к маршрутам с
помощью свойства meta. Для заголовка страницы используется
поле title:
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
const routes = [
{
path: '/',
component: Home,
meta: { title: 'Главная' }
},
{
path: '/about',
component: About,
meta: { title: 'О проекте' }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
Ключевой момент: любое поле meta доступно через объект
маршрута to.meta в хуках навигации.
afterEachСамый распространённый способ обновления заголовка — это глобальный
навигационный хук afterEach:
router.afterEach((to) => {
document.title = to.meta.title || 'Default Title'
})
to.meta.title — заголовок, заданный в маршруте.Этот метод гарантирует, что заголовок страницы всегда синхронизирован с текущим маршрутом.
Если заголовок должен зависеть от параметров маршрута, можно использовать функцию для генерации строки:
const routes = [
{
path: '/user/:id',
component: UserProfile,
meta: {
title: route => `Профиль пользователя ${route.params.id}`
}
}
]
router.afterEach((to) => {
const title = typeof to.meta.title === 'function'
? to.meta.title(to)
: to.meta.title
document.title = title || 'Default Title'
})
Особенности такого подхода:
meta.title может быть строкой или функцией, принимающей
объект маршрута to.Если заголовок зависит от данных, получаемых асинхронно (например, из
API), рекомендуется использовать beforeResolve:
router.beforeResolve(async (to, from, next) => {
if (to.meta.asyncTitle) {
const data = await fetchTitle(to.params.id)
document.title = data
} else {
document.title = to.meta.title || 'Default Title'
}
next()
})
beforeResolve вызывается перед завершением навигации,
но после разрешения всех асинхронных компонентов.Вложенные маршруты могут иметь собственные метаданные. Для построения
заголовка с учётом иерархии используют цепочку matched:
router.afterEach((to) => {
const nearestWithTitle = to.matched.slice().reverse().find(r => r.meta && r.meta.title)
if (nearestWithTitle) {
document.title = nearestWithTitle.meta.title
} else {
document.title = 'Default Title'
}
})
to.matched — массив маршрутов от родителя к
дочернему.slice().reverse() позволяет приоритетно
брать заголовок из самого конкретного (дочернего) маршрута.Можно обновлять заголовок внутри компонентов через watch
маршрута:
export default {
watch: {
$route(to) {
document.title = to.meta.title || 'Default Title'
}
},
mounted() {
document.title = this.$route.meta.title || 'Default Title'
}
}
<title>.Управление заголовками в Vue Router становится гибким благодаря
комбинации meta, глобальных хуков и функций. Это позволяет
создавать как простые статические заголовки, так и динамические,
зависящие от параметров маршрута или асинхронных данных.