Для интеграции 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.
Smooth Scroll может конфликтовать с Vue Router, если
переходы происходят через <router-link> с
hash. Для корректной работы:
const router = createRouter({
history: createWebHistory(),
routes: [...],
scrollBehavior(to, from, savedPosition) {
return false; // запрещаем дефолтное поведение
},
});
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 – позволяет автоматически изменять хеш в
адресной строке.destroy().Smooth Scroll полностью совместим с реактивными и динамическими компонентами. Важно:
mounted или
$nextTick.unmounted.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.