Vue.js + 1С-Битрикс: избранное без перезагрузки

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Vue.js + 1С-Битрикс: избранное без перезагрузки
Средний
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1330
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    924
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    672
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    815
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    714
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1051

В интернет-магазине на 1С-Битрикс без избранного пользователи выкручиваются через список сравнения или корзину. Оба варианта перезагружают страницу — 2–3 секунды ожидания на каждое действие. Стандартный компонент не поддерживает гостей, а доработки плодят костыли. За 5 лет мы внедрили полноценные wishlist-компоненты в 30+ проектах — от небольших каталогов до крупных маркетплейсов. Средняя конверсия в избранное после внедрения растёт на 30%, а время загрузки страницы падает в 5 раз. Экономия бюджета на поддержке — до 20%, окупаемость инвестиций — 6–12 месяцев.

Как реализовать избранное для гостей и авторизованных?

Если пользователь не авторизован — используем только localStorage. Для постоянного хранения нужна база данных и механизм мержа: при авторизации гостевое избранное из localStorage объединяется с серверным. Оптимистичное обновление UI (см. Wikipedia: Оптимистическая блокировка) сокращает количество кликов на 40%. Идентификация по токену в cookie восстанавливает список после очистки кэша. В наших проектах конверсия из избранного в корзину достигает 15–20%.

Зачем нужна подписка на наличие?

Для товаров не в наличии пользователи могут подписаться на уведомление. Агент Битрикс раз в час проверяет остатки (QUANTITY > 0) и отправляет email через CEvent::Send(). Это повышает лояльность и конверсию. Как указано в документации 1С-Битрикс, агенты выполняют задачи по расписанию. Товары в топе избранного с нулевыми остатками — кандидаты на приоритетное пополнение.

Как ускорить UI с помощью Pinia?

Главная боль стандартного избранного — перезагрузка страницы при каждом добавлении. Vue.js с библиотекой Pinia и оптимистичным обновлением решает это кардинально: пользователь видит мгновенную смену состояния, а запрос к серверу уходит параллельно. При ошибке состояние откатывается. Весь UI отзывчивый, никаких спиннеров. Vue.js в 5 раз быстрее стандартного компонента сравнения.

Pinia store для избранного

// stores/wishlistStore.ts
export const useWishlistStore = defineStore('wishlist', () => {
    const items    = ref<number[]>([])
    const loading  = ref<Set<number>>(new Set())

    async function init() {
        if (isLoggedIn()) {
            const data = await api.get('/local/api/wishlist/')
            items.value = data.map((i: any) => i.product_id)
        } else {
            const stored = localStorage.getItem('wishlist')
            items.value  = stored ? JSON.parse(stored) : []
        }
    }

    async function toggle(productId: number) {
        if (loading.value.has(productId)) return
        loading.value.add(productId)
        const wasAdded = items.value.includes(productId)
        if (wasAdded) {
            items.value = items.value.filter(id => id !== productId)
        } else {
            items.value.push(productId)
        }
        if (isLoggedIn()) {
            try {
                await api.post('/local/api/wishlist/' + (wasAdded ? 'remove' : 'add') + '/', { product_id: productId })
            } catch (e) {
                if (wasAdded) items.value.push(productId)
                else items.value = items.value.filter(id => id !== productId)
            }
        } else {
            localStorage.setItem('wishlist', JSON.stringify(items.value))
        }
        loading.value.delete(productId)
    }

    const isInWishlist = (id: number) => items.value.includes(id)
    const count        = computed(() => items.value.length)

    return { items, loading, init, toggle, isInWishlist, count }
})

Кнопка избранного на карточке товара

<!-- WishlistButton.vue -->
<template>
  <button
    :class="['wishlist-btn', { 'wishlist-btn--active': isAdded, 'wishlist-btn--loading': isLoading }]"
    @click.prevent="handleToggle"
    :aria-label="isAdded ? 'Убрать из избранного' : 'В избранное'"
  >
    <HeartIcon :filled="isAdded" />
  </button>
</template>

<script setup lang="ts">
const props  = defineProps<{ productId: number }>()
const store  = useWishlistStore()
const isAdded   = computed(() => store.isInWishlist(props.productId))
const isLoading = computed(() => store.loading.has(props.productId))

async function handleToggle() {
    await store.toggle(props.productId)
    showToast(isAdded.value ? 'Добавлено в избранное' : 'Удалено из избранного')
}
</script>

Тост-уведомления — ненавязчивые сообщения в углу экрана, которые исчезают через 3 секунды. Реализуются через отдельный Toast-компонент или небольшую библиотеку.

Схема базы данных
CREATE TABLE b_user_wishlist (
    ID          SERIAL PRIMARY KEY,
    USER_ID     INT NOT NULL REFERENCES b_user(ID),
    LIST_NAME   VARCHAR(255) DEFAULT 'default',
    DATE_CREATE TIMESTAMP DEFAULT NOW()
);

CREATE TABLE b_wishlist_items (
    ID          SERIAL PRIMARY KEY,
    LIST_ID     INT NOT NULL REFERENCES b_user_wishlist(ID),
    PRODUCT_ID  INT NOT NULL,
    DATE_ADD    TIMESTAMP DEFAULT NOW(),
    UNIQUE (LIST_ID, PRODUCT_ID)
);

CREATE TABLE b_availability_subscriptions (
    USER_ID    INT NOT NULL,
    PRODUCT_ID INT NOT NULL,
    EMAIL      VARCHAR(255),
    DATE_ADD   TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (USER_ID, PRODUCT_ID)
);

Для простого варианта (один список) таблица b_user_wishlist не нужна — достаточно двух полей: USER_ID и PRODUCT_ID.

Мерж гостевого и авторизованного избранного

При логине пользователя вызывается серверный метод мержа, а на фронтенде — соответствующий обработчик. Код серверной части (PHP) использует метод merge() в таблице. В JavaScript логика выглядит так:

async function onUserLogin() {
    const guestIds = JSON.parse(localStorage.getItem('wishlist') ?? '[]')
    if (guestIds.length) {
        const merged = await api.post('/local/api/wishlist/merge/', { ids: guestIds })
        items.value  = merged
        localStorage.removeItem('wishlist')
    } else {
        await init()
    }
}

Также реализована подписка на наличие: агент Битрикс раз в час проверяет таблицу подписок и отправляет письма через CEvent::Send() при появлении товара на складе (QUANTITY > 0).

Аналитика избранного

Данные избранного — ценный сигнал о спросе. Мы строим аналитический дашборд: топ-50 товаров в избранном, конверсия «из избранного в покупку» через JOIN с b_sale_basket. Это позволяет принимать обоснованные решения по закупкам и маркетингу.

Сравнение подходов: Vue.js vs стандартное избранное

Критерий Standard Bitrix Vue.js Wishlist
Время отклика 2–3 сек (полная перезагрузка) <100 мс (оптимистичное обновление)
Поддержка гостей Нет (только авторизованные) Да (localStorage)
Мерж гостей Нет Да, автоматический при логине
Подписка на наличие Через модуль (сложно) Встроена
Аналитика Только корзина Дашборд избранного

Пошаговая инструкция по внедрению

  1. Анализ: определите, нужен ли один список или несколько, нужна ли подписка на наличие.
  2. Проектирование БД: создайте таблицы под вашу модель.
  3. Разработка API: реализуйте REST-методы для CRUD избранного.
  4. Реализация фронтенда: создайте Pinia store и компонент кнопки.
  5. Интеграция мержа: добавьте логику при авторизации.
  6. Тестирование: проверьте сценарии с гостями, авторизованными, сбросом кэша.
  7. Деплой: выкатите на боевой сервер, настройте мониторинг.

Сроки разработки

Вариант Что входит Срок
Guest-only wishlist localStorage, кнопки, страница 4–7 дней
Авторизованный с персистом База, API, мерж 1–2 недели
+ Мульти-списки, подписка Управление списками, уведомления +1–2 недели

Что входит в работу

Мы предоставляем полный цикл: архитектура, реализация, интеграция, документация, тестирование и поддержка. Свяжитесь с нами для консультации — рассчитаем сроки и стоимость за 1 рабочий день. Закажите разработку wishlist под ключ и получите готовое решение с гарантией 6 месяцев.