Разработка CRM-карточек на Vue.js для Битрикс24

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка CRM-карточек на Vue.js для Битрикс24
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка CRM-карточек на Vue.js для Битрикс24

Стандартная карточка сделки, контакта или лида в Битрикс24 покрывает 80% потребностей. Проблема начинается в оставшихся 20%: нужно отобразить данные из внешней системы прямо в карточке, добавить кнопку с нетривиальным действием, показать связанные объекты в виде таблицы или сделать поля зависимыми друг от друга. Битрикс24 предоставляет механизм встройки — placement — через который Vue-приложение монтируется прямо внутрь карточки CRM.

Механизм placement в CRM

BX24.placement.getInterface() возвращает информацию о текущем контексте — где именно открыта карточка и какой объект отображается:

window.BX24.init(() => {
  BX24.placement.getInterface((result) => {
    // result: { ID, ENTITY_TYPE_NAME, ENTITY_TYPE_ID }
    // например: { ID: 123, ENTITY_TYPE_NAME: 'deal', ENTITY_TYPE_ID: 2 }
    initApp(result)
  })
})

Типы placement для CRM:

  • CRM_DEAL_DETAIL_TAB — вкладка в карточке сделки
  • CRM_CONTACT_DETAIL_TAB — вкладка в карточке контакта
  • CRM_LEAD_DETAIL_TAB — вкладка в карточке лида
  • CRM_DEAL_DETAIL_ACTIVITY — блок активностей

Архитектура Vue-карточки

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'

window.BX24.init(async () => {
  const placement = await getPlacement()
  const auth = BX24.getAuth()

  const app = createApp(App)
  app.use(createPinia())
  app.provide('entityId', placement.ID)
  app.provide('entityType', placement.ENTITY_TYPE_NAME)
  app.provide('auth', auth)
  app.mount('#app')
})

function getPlacement() {
  return new Promise(resolve => BX24.placement.getInterface(resolve))
}

Pinia для управления состоянием карточки — оптимальный выбор: поддерживает DevTools, TypeScript, работает без this.

Загрузка данных сущности

// stores/dealStore.js
import { defineStore } from 'pinia'
import { inject } from 'vue'

export const useDealStore = defineStore('deal', {
  state: () => ({
    deal: null,
    relatedContacts: [],
    externalData: null,
    loading: false,
  }),

  actions: {
    async loadDeal(id) {
      this.loading = true
      const [deal, contacts] = await Promise.all([
        bx24Call('crm.deal.get', { id }),
        bx24Call('crm.deal.contact.items.get', { id }),
      ])
      this.deal = deal
      this.relatedContacts = contacts
      this.loading = false
    },

    async loadExternalData(dealId) {
      // Данные из внешней системы через собственный API
      const res = await fetch(`/api/deals/${dealId}/external`)
      this.externalData = await res.json()
    }
  }
})

Обновление полей карточки

Обновление CRM-объекта через REST:

async function updateDeal(id, fields) {
  return new Promise((resolve, reject) => {
    BX24.callMethod('crm.deal.update', {
      id,
      fields,
    }, (result) => {
      if (result.error()) reject(result.error())
      else resolve(result.data())
    })
  })
}

Для нескольких полей одновременно — батч-запрос. Не обновляйте поля по одному в цикле — это создаёт очередь запросов и замедляет интерфейс.

Пользовательские кнопки и действия

Добавление кнопки в тулбар карточки через BX24.placement.bindEvent:

BX24.placement.bindEvent('onAppOptionsSave', () => {
  // Реакция на сохранение настроек приложения
})

// Кнопка действия отправляется через callMethod
BX24.callMethod('placement.bind', {
  PLACEMENT: 'CRM_DEAL_DETAIL_TAB',
  HANDLER: 'https://my-app.example.com/',
  TITLE: 'Моя вкладка',
  DESCRIPTION: 'Расширение CRM-карточки',
})

В самом Vue-приложении кнопки — обычные компоненты с эмитом событий и вызовом REST-методов.

Отображение данных из внешних систем

Типичный кейс — показать в карточке сделки историю заказов клиента из 1С или ERP:

<template>
  <div class="external-orders">
    <div v-if="store.loading" class="loader">Загрузка...</div>
    <table v-else>
      <thead>
        <tr>
          <th>Номер заказа</th>
          <th>Дата</th>
          <th>Сумма</th>
          <th>Статус</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="order in store.externalData?.orders" :key="order.id">
          <td>{{ order.number }}</td>
          <td>{{ formatDate(order.date) }}</td>
          <td>{{ formatMoney(order.total) }}</td>
          <td>
            <span :class="statusClass(order.status)">
              {{ order.statusLabel }}
            </span>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

Серверная часть — прокси-эндпоинт, который авторизуется в 1С, получает данные и возвращает JSON. Битрикс24 не ходит в 1С напрямую из фронта.

Реактивное обновление при изменениях

Если пользователь изменил поле в стандартной карточке и переключился на вашу вкладку — нужно перезагрузить данные:

// Проверяем актуальность при фокусе на вкладке
document.addEventListener('visibilitychange', () => {
  if (!document.hidden) store.loadDeal(entityId)
})

Либо — подписка на события через BX24.placement.bindEvent('onAppOptionsSave', callback).

Стилизация под интерфейс Битрикс24

Используйте CSS-переменные и нейтральные компоненты. Битрикс24 имеет свою дизайн-систему, и кастомная вкладка должна выглядеть органично. Минимум теней, тонкие границы, шрифты без serif. Headless UI или собственные компоненты — предпочтительнее тяжёлых UI-библиотек с яркими темами.

Сроки выполнения

Простая вкладка с отображением данных из REST и кнопкой действия — 2–4 рабочих дня. Полноценная вкладка с данными из внешней системы, редактированием и синхронизацией — 1–3 недели в зависимости от количества сущностей и сложности логики.