Прокрутка к якорям

В Vue Router возможность прокрутки к якорям реализуется с помощью опции scrollBehavior, которая задаётся при создании экземпляра маршрутизатора. Эта опция позволяет контролировать поведение страницы при навигации между маршрутами, включая возврат к определённым позициям, сохранение предыдущего положения или прокрутку к элементам с идентификаторами (якорям).


Определение scrollBehavior

Функция scrollBehavior принимает три параметра:

scrollBehavior(to, from, savedPosition)
  • to – объект маршрута, на который происходит переход. Содержит информацию о маршруте, включая путь, параметры и хэш (например, #section1).
  • from – объект маршрута, с которого осуществляется переход.
  • savedPosition – объект с координатами прокрутки { x, y }, если переход происходит с использованием кнопок «Назад» или «Вперед» браузера.

Функция должна возвращать объект с координатами или null:

const router = new VueRouter({
  routes: [...],
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    } else if (to.hash) {
      return { el: to.hash };
    } else {
      return { top: 0 };
    }
  }
});

Прокрутка к элементам по хэшу

Если маршрут содержит хэш, например /about#team, Vue Router может прокрутить страницу к элементу с идентификатором team. Для этого используется объект:

return { el: to.hash, beh * avior: 'smooth' };

Параметры:

  • el – строка CSS-селектора или DOM-элемент, к которому будет осуществляться прокрутка.
  • behavior – опционально, определяет плавность прокрутки ('auto' по умолчанию или 'smooth' для анимации).

Пример с плавной прокруткой:

scrollBehavior(to, from, savedPosition) {
  if (to.hash) {
    return { el: to.hash, beh * avior: 'smooth' };
  }
  return { top: 0 };
}

Прокрутка при переходах назад и вперёд

Если пользователь использует кнопки навигации браузера, savedPosition содержит координаты предыдущей прокрутки:

if (savedPosition) {
  return savedPosition;
}

Это обеспечивает естественное поведение, аналогичное обычной веб-странице, где возвращение на предыдущую страницу сохраняет позицию прокрутки.


Асинхронная прокрутка

Иногда элемент с хэшем может появляться на странице с задержкой (например, после загрузки данных). В таких случаях scrollBehavior может возвращать промис, чтобы прокрутка происходила после полной отрисовки контента:

scrollBehavior(to, from, savedPosition) {
  if (to.hash) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({ el: to.hash, beh * avior: 'smooth' });
      }, 500);
    });
  }
  return { top: 0 };
}

Промис гарантирует, что прокрутка выполнится после того, как DOM будет готов.


Использование offset

Для фиксированных шапок или навигационных панелей иногда требуется сдвиг позиции прокрутки:

scrollBehavior(to) {
  if (to.hash) {
    return { el: to.hash, top: 100, beh * avior: 'smooth' };
  }
  return { top: 0 };
}
  • top – задаёт дополнительный сдвиг в пикселях от верхнего края страницы.

Варианты возврата позиции

  • По умолчанию: прокрутка в начало страницы { top: 0 }.
  • К сохранённой позиции: { x: savedPosition.x, y: savedPosition.y }.
  • К элементу по селектору: { el: to.hash }.
  • С асинхронной задержкой или кастомным offset.

Особенности использования с динамическими маршрутами

Если путь маршрута содержит параметры, прокрутка к якорю сработает только после того, как маршрут будет полностью загружен и компонент отрисован. В противном случае el может быть null. Для динамических компонентов рекомендуется использовать nextTick внутри промиса:

scrollBehavior(to) {
  if (to.hash) {
    return new Promise((resolve) => {
      Vue.nextTick(() => {
        resolve({ el: to.hash });
      });
    });
  }
  return { top: 0 };
}

Это гарантирует корректное нахождение элемента в DOM.


Рекомендации по использованию

  • Всегда проверять наличие хэша to.hash перед прокруткой.
  • Для плавной анимации использовать beh * avior: 'smooth'.
  • Для страниц с динамическим контентом использовать промис или Vue.nextTick.
  • При наличии фиксированных элементов добавлять top или кастомный offset.
  • Не забывать возвращать { top: 0 } или savedPosition, чтобы стандартное поведение прокрутки сохранялось.

Этот механизм делает Vue Router гибким инструментом для управления прокруткой страниц, особенно в одностраничных приложениях, где необходимо сочетать навигацию по маршрутам и внутренние якоря.