Использование в Vue.js

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

npm install stickybits --save

После установки можно импортировать библиотеку в компонент Vue:

import stickybits from 'stickybits';

Или использовать глобально через подключение в main.js:

import Vue from 'vue';
import stickybits from 'stickybits';

Vue.prototype.$stickybits = stickybits;

Такое подключение позволяет обращаться к Stickybits через this.$stickybits внутри компонентов.


Инициализация sticky-элементов в компоненте

Stickybits работает с DOM-элементами, поэтому инициализация чаще всего производится в хуке жизненного цикла mounted, когда DOM уже доступен:

export default {
  name: 'StickyExample',
  mounted() {
    // Простой пример применения stickybits
    stickybits('.sticky-element', {
      stickyBitStickyOffset: 0, // смещение от верха окна
      useStickyClasses: true,   // добавление CSS-классов при фиксации
      verticalPosition: 'top'   // фиксация сверху
    });
  }
}

Ключевые параметры:

  • stickyBitStickyOffset — задаёт отступ от верхнего края при фиксации.
  • useStickyClasses — автоматически добавляет CSS-классы .is-sticky, .is-stuck и .stickybit для удобного стилирования.
  • verticalPosition — позиция закрепления (top или bottom).

Работа с реактивными данными Vue

Если sticky-элемент зависит от реактивных данных, например, появляется или исчезает в зависимости от состояния, нужно обновлять Stickybits после изменения DOM. В Vue это делается через $nextTick:

export default {
  data() {
    return {
      showSticky: false
    };
  },
  methods: {
    toggleSticky() {
      this.showSticky = !this.showSticky;
      this.$nextTick(() => {
        stickybits('.sticky-element', {
          stickyBitStickyOffset: 10,
          useStickyClasses: true
        });
      });
    }
  }
}

Это гарантирует, что Stickybits инициализируется только после того, как элемент появился в DOM.


Очистка и повторная инициализация

Для динамически меняющихся компонентов важно корректно очищать старые экземпляры Stickybits, чтобы не создавать лишние обработчики:

export default {
  mounted() {
    this.stickyInstance = stickybits('.sticky-element', { useStickyClasses: true });
  },
  beforeDestroy() {
    if (this.stickyInstance && this.stickyInstance.cleanup) {
      this.stickyInstance.cleanup();
    }
  }
}

Метод cleanup() удаляет все классы и слушатели событий, освобождая память и предотвращая конфликты при повторной инициализации.


Использование с Vue-рефами

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

<template>
  <div ref="stickyElement">Закрепляемый блок</div>
</template>

<script>
import stickybits from 'stickybits';

export default {
  mounted() {
    stickybits(this.$refs.stickyElement, {
      stickyBitStickyOffset: 20,
      useStickyClasses: true
    });
  }
}
</script>

Использование ref повышает стабильность работы и уменьшает вероятность ошибки при изменении DOM.


Стилизация через CSS-классы

Stickybits добавляет следующие CSS-классы:

  • .stickybit — применяемый к каждому элементу.
  • .is-sticky — активен, когда элемент закреплён в окне.
  • .is-stuck — активен, когда элемент достиг нижней границы контейнера.

Пример базовой стилизации:

.stickybit {
  transition: all 0.3s ease;
}

.is-sticky {
  background-color: #f8f8f8;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}

.is-stuck {
  opacity: 0.8;
}

Классы позволяют гибко настраивать внешний вид элементов без прямого вмешательства в JavaScript.


Интеграция с компонентами Vue с динамическим контентом

При работе с ленивой загрузкой или условным рендерингом (v-if, v-for) Stickybits нужно вызывать после того, как элементы будут добавлены в DOM:

<template>
  <div v-for="item in items" :key="item.id" class="sticky-element">{{ item.text }}</div>
</template>

<script>
import stickybits from 'stickybits';

export default {
  data() {
    return {
      items: []
    };
  },
  methods: {
    loadItems() {
      this.items = fetchItems(); // возвращает массив
      this.$nextTick(() => {
        stickybits('.sticky-element', { useStickyClasses: true });
      });
    }
  }
}
</script>

$nextTick гарантирует, что sticky-элементы корректно инициализируются после рендеринга списка.


Совмещение с Vue Router

Если на странице используются переходы между маршрутами, Stickybits необходимо инициализировать заново после загрузки компонента маршрута. Например, в mounted компонента маршрута:

mounted() {
  stickybits('.sticky-element', { useStickyClasses: true });
}

Для SPA это предотвращает потерю фиксации при переходе между страницами.


Расширенные возможности

Stickybits поддерживает:

  • parent — указание родительского контейнера для ограничения зоны фиксации.
  • scrollEl — прокручиваемый контейнер, отличный от window.
  • stickyBitUpdate — метод обновления состояния sticky вручную:
this.stickyInstance.update();

Эти возможности позволяют интегрировать Stickybits в сложные интерфейсы с кастомными прокрутками и адаптивными макетами.


Практический пример в Vue 3 с Composition API

<template>
  <div ref="stickyRef" class="sticky-element">Фиксированный блок</div>
</template>

<script>
import { onMounted, ref, onBeforeUnmount } from 'vue';
import stickybits from 'stickybits';

export default {
  setup() {
    const stickyRef = ref(null);
    let stickyInstance = null;

    onMounted(() => {
      stickyInstance = stickybits(stickyRef.value, { stickyBitStickyOffset: 10, useStickyClasses: true });
    });

    onBeforeUnmount(() => {
      if (stickyInstance && stickyInstance.cleanup) stickyInstance.cleanup();
    });

    return { stickyRef };
  }
}
</script>

Такой подход полностью соответствует современному Vue 3, гарантируя корректное создание и уничтожение sticky-элементов.