Vue.js интеграция

Для интеграции Smooth Scroll в проект на Vue.js необходимо сначала установить пакет через npm или yarn:

npm install smooth-scroll
# или
yarn add smooth-scroll

После установки библиотеку можно подключить в компоненте Vue либо глобально через main.js или main.ts для всего приложения.

Глобальное подключение

В main.js импортируется Smooth Scroll и инициализируется на всех ссылках с якорями:

import { createApp } from 'vue';
import App from './App.vue';
import SmoothScroll from 'smooth-scroll';

const app = createApp(App);

// Инициализация Smooth Scroll на всех ссылках с атрибутом href, начинающимся с #
new SmoothScroll('a[href*="#"]', {
  speed: 800,
  offset: 50,
  easing: 'easeInOutCubic',
});

app.mount('#app');

Пояснение параметров:

  • speed – скорость прокрутки в миллисекундах.
  • offset – смещение от верхнего края страницы, полезно при фиксированном header.
  • easing – функция плавности анимации; поддерживаются стандартные кривые: linear, easeInOutCubic и другие.

Локальная инициализация в компоненте

Иногда требуется включать плавный скролл только для конкретного компонента. Для этого Smooth Scroll можно подключить внутри mounted:

<script>
import SmoothScroll from 'smooth-scroll';

export default {
  name: 'SectionNavigator',
  mounted() {
    this.scroll = new SmoothScroll(this.$refs.links, {
      speed: 600,
      offset: 70,
      easing: 'easeInOutQuad',
    });
  },
  unmounted() {
    if (this.scroll) {
      this.scroll.destroy();
    }
  },
};
</script>

<template>
  <div>
    <a v-for="section in sections" :key="section.id" :href="`#${section.id}`" ref="links">{{ section.title }}</a>
  </div>
</template>

Ключевой момент: при локальной инициализации важно корректно уничтожать экземпляр Smooth Scroll через destroy(), чтобы избежать утечек памяти при переходе между компонентами.


Привязка к динамическим элементам

Если ссылки генерируются динамически через v-for или подгружаются через API, инициализацию Smooth Scroll нужно проводить после того, как элементы отрендерились:

this.$nextTick(() => {
  this.scroll = new SmoothScroll('a[href*="#"]', {
    speed: 500,
    offset: 80,
    easing: 'easeOutQuart',
  });
});

$nextTick гарантирует, что все ссылки присутствуют в DOM перед созданием экземпляра Smooth Scroll.


Использование с динамическими роутами Vue Router

Smooth Scroll может конфликтовать с Vue Router, если переходы происходят через <router-link> с hash. Для корректной работы:

  1. Отключить стандартную прокрутку Vue Router:
const router = createRouter({
  history: createWebHistory(),
  routes: [...],
  scrollBehavior(to, from, savedPosition) {
    return false; // запрещаем дефолтное поведение
  },
});
  1. Применить Smooth Scroll вручную после перехода:
router.afterEach((to) => {
  if (to.hash) {
    const scroll = new SmoothScroll();
    const target = document.querySelector(to.hash);
    if (target) scroll.animateScroll(target);
  }
});

Это позволяет плавно перемещаться к элементам с id после навигации, сохраняя контроль над скоростью и смещением.


Настройка кастомных кривых анимации

Smooth Scroll поддерживает кастомные функции easing для уникального поведения:

function customEasing(t, b, c, d) {
  t /= d / 2;
  if (t < 1) return c / 2 * t * t + b;
  t--;
  return -c / 2 * (t * (t - 2) - 1) + b;
}

new SmoothScroll('a[href*="#"]', {
  speed: 700,
  easing: customEasing,
});

customEasing принимает параметры: t – текущее время, b – начальная позиция, c – смещение, d – длительность анимации.


Управление событиями и колбэками

Smooth Scroll позволяет подписываться на события для интеграции с другими компонентами:

const scroll = new SmoothScroll('a[href*="#"]');

scroll.animateScroll(target, null, {
  updateURL: true,
  offset: 100,
  after: () => {
    console.log('Прокрутка завершена');
  },
  before: () => {
    console.log('Начало прокрутки');
  },
});
  • before – вызывается перед стартом анимации.
  • after – вызывается после завершения прокрутки.
  • updateURL – позволяет автоматически изменять хеш в адресной строке.

Оптимизация производительности

  1. Дебаунс обработчиков: при использовании с динамическими ссылками, которые часто обновляются, обёрнуть инициализацию в debounce.
  2. Удаление экземпляров: при переходе между страницами или компонентами обязательно вызывать destroy().
  3. Ограничение селектора: использовать точные селекторы, чтобы Smooth Scroll не прослушивал лишние элементы.

Совместимость с компонентами Vue 3

Smooth Scroll полностью совместим с реактивными и динамическими компонентами. Важно:

  • Инициализировать после рендера через mounted или $nextTick.
  • Уничтожать экземпляры в unmounted.
  • Использовать корректные селекторы и refs для динамических ссылок.
  • В случае работы с Vue Router отключать стандартное поведение scrollBehavior.

Пример комплексной интеграции

<script>
import SmoothScroll from 'smooth-scroll';

export default {
  name: 'AppNavigation',
  mounted() {
    this.$nextTick(() => {
      this.scroll = new SmoothScroll('a[href^="#"]', {
        speed: 600,
        offset: 60,
        easing: 'easeInOutCubic',
        updateURL: true,
      });
    });
  },
  unmounted() {
    if (this.scroll) this.scroll.destroy();
  },
};
</script>

<template>
  <nav>
    <ul>
      <li><a href="#section1">Раздел 1</a></li>
      <li><a href="#section2">Раздел 2</a></li>
      <li><a href="#section3">Раздел 3</a></li>
    </ul>
  </nav>

  <section id="section1">Контент 1</section>
  <section id="section2">Контент 2</section>
  <section id="section3">Контент 3</section>
</template>

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