Реактивность и привязка данных

Bliss.js — это легковесная библиотека для работы с DOM, ориентированная на удобное управление состоянием и реактивность интерфейса без сложного синтаксиса. Основная сила библиотеки заключается в автоматическом отслеживании изменений данных и обновлении DOM при этих изменениях.


Принцип реактивности

Реактивность в Bliss.js строится вокруг идеи наблюдаемых объектов. Любой объект или массив, обернутый с помощью реактивной функции bliss.observable, становится «живым» — его свойства отслеживаются, и при изменении автоматически вызываются привязанные функции обновления интерфейса.

const state = bliss.observable({
    count: 0,
    user: { name: 'Alice', age: 25 }
});

В этом примере state.count и state.user.name становятся реактивными. Любое изменение этих значений мгновенно отражается на интерфейсе при корректной привязке.


Привязка данных к DOM

Bliss.js предоставляет функцию bliss.bind, которая связывает значение свойства объекта с атрибутами или содержимым DOM-элементов. Эта привязка может быть как односторонней, так и двусторонней.

Пример односторонней привязки текста:

const span = document.querySelector('#counter');
bliss.bind(span, 'textContent', state, 'count');

Теперь любое изменение state.count автоматически обновит содержимое элемента <span id="counter">.

Двусторонняя привязка с полем ввода:

const input = document.querySelector('#nameInput');
bliss.bind(input, 'value', state.user, 'name', { twoWay: true });

При этом любое изменение текста в input изменит state.user.name, а изменение свойства из кода отразится в поле ввода.


Реактивные вычисляемые свойства

Bliss.js поддерживает вычисляемые свойства, которые автоматически пересчитываются при изменении зависимых данных. Для этого используется функция bliss.computed.

const fullName = bliss.computed(() => `${state.user.name} (${state.user.age})`);
bliss.bind(document.querySelector('#fullName'), 'textContent', fullName);

Здесь fullName обновляется автоматически при изменении state.user.name или state.user.age, и DOM элемент отображает актуальное значение без дополнительных обработчиков событий.


Отслеживание массивов

Массивы в Bliss.js также могут быть реактивными. Для этого используют bliss.observable с массивом. Библиотека автоматически отслеживает добавление, удаление и изменение элементов.

const tasks = bliss.observable([
    { title: 'Купить продукты', done: false },
    { title: 'Помыть машину', done: true }
]);

const list = document.querySelector('#taskList');
tasks.forEach(task => {
    const li = document.createElement('li');
    bliss.bind(li, 'textContent', task, 'title');
    list.appendChild(li);
});

Любое добавление нового элемента через tasks.push({ title: 'Новая задача', done: false }) автоматически добавит элемент в DOM при использовании методов расширенной интеграции Bliss.js с коллекциями.


Реактивные события

Bliss.js позволяет привязывать обработчики событий к реактивным объектам, сохраняя синхронность состояния и DOM. Это особенно полезно для интерактивных интерфейсов.

const button = document.querySelector('#increment');
button.addEventListener('click', () => {
    state.count += 1;
});

После каждого клика значение state.count увеличивается, а привязка к элементу <span> автоматически обновляется, благодаря реактивной системе.


Работа с атрибутами и стилями

Привязка не ограничивается текстом. Bliss.js поддерживает динамическое обновление любых атрибутов и стилей:

const box = document.querySelector('#box');
bliss.bind(box, 'style.backgroundColor', state, 'user.favoriteColor');
bliss.bind(box, 'className', bliss.computed(() => state.user.age > 30 ? 'adult' : 'young'));

При изменении state.user.favoriteColor или state.user.age внешний вид элемента обновляется мгновенно.


Ленивая и условная реактивность

Для оптимизации производительности Bliss.js предлагает ленивую реактивность, когда вычисления происходят только при необходимости, и условные вычисления через методы bliss.computed с условными выражениями:

const message = bliss.computed(() => state.count > 10 ? 'Много!' : 'Мало');
bliss.bind(document.querySelector('#message'), 'textContent', message);

DOM обновляется только при изменении значения, влияющего на результат вычисления.


Сводка ключевых механизмов

  • bliss.observable(obj) — делает объект реактивным.
  • bliss.bind(element, property, source, key, options) — привязывает DOM к реактивному значению.
  • bliss.computed(fn) — создает вычисляемое свойство, автоматически пересчитывающееся при изменениях зависимостей.
  • Двусторонняя привязка через { twoWay: true }.
  • Поддержка реактивных массивов и автоматическое обновление коллекций.
  • Привязка атрибутов, стилей, классов и текста.
  • Оптимизация через ленивую и условную реактивность.

Bliss.js объединяет простоту синтаксиса и мощь реактивного обновления интерфейса, позволяя создавать интерактивные веб-приложения без сложной структуры и громоздких библиотек.