Vue Router предоставляет встроенные механизмы для управления
поведением прокрутки при навигации между маршрутами. Веб-приложения с
динамическим контентом часто требуют восстановления позиции скролла при
возврате на предыдущую страницу или при переходе между секциями. Для
этого используется опция scrollBehavior при создании
экземпляра роутера.
scrollBehaviorОпция scrollBehavior принимает функцию с тремя
параметрами: to, from и
savedPosition. Она вызывается при каждой навигации и
позволяет определить, куда прокрутить страницу. Стандартная сигнатура
выглядит следующим образом:
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
],
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return { top: 0 };
}
},
});
savedPosition используется только при навигации назад
или вперёд в истории браузера. Если она существует, возвращается объект
с координатами { x, y }.{ top: 0 } или к конкретному элементу через селектор.Vue Router позволяет прокручивать страницу к элементу, используя
CSS-селектор. Для этого возвращается объект вида
{ el: '#id', beh * avior: 'smooth' }:
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: to.hash,
beh * avior: 'smooth',
};
}
return { top: 0 };
}
to.hash содержит значение якоря в URL, например
#section1.behavior может быть 'auto' (по
умолчанию) или 'smooth' для плавной прокрутки.Функция scrollBehavior может быть асинхронной, возвращая
Promise. Это полезно, если элементы загружаются динамически
и необходимо дождаться их появления на странице перед прокруткой:
scrollBehavior(to, from, savedPosition) {
return new Promise((resolve) => {
setTimeout(() => {
if (to.hash) {
resolve({ el: to.hash });
} else {
resolve({ top: 0 });
}
}, 300);
});
}
Такой подход гарантирует корректное позиционирование даже при ленивой загрузке компонентов или контента.
При использовании вложенных маршрутов важно учитывать, что
scrollBehavior вызывается один раз за полную навигацию. Если на странице
несколько <router-view>, можно реализовать
индивидуальное поведение для каждого уровня маршрута, проверяя
to.matched:
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
}
const deepestRoute = to.matched[to.matched.length - 1];
if (deepestRoute.meta.scrollToTop === false) {
return false;
}
return { top: 0 };
}
to.matched — массив совпавших маршрутов от
родительского до вложенного.meta позволяет настраивать прокрутку на
уровне отдельных маршрутов.savedPosition при навигации
назад/вперед, чтобы сохранить привычное поведение браузера.beh * avior: 'smooth'.to.hash и meta свойства маршрута.scrollBehaviorscrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
}
if (to.hash) {
return { el: to.hash, beh * avior: 'smooth' };
}
if (to.meta.scrollToTop === false) {
return false;
}
return { top: 0 };
}
В этом примере реализованы все основные сценарии: возврат к предыдущей позиции, прокрутка к якорю, отключение прокрутки для определённых маршрутов и стандартная прокрутка на верх страницы по умолчанию. Такой подход обеспечивает предсказуемое и комфортное поведение для пользователя.