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

Petite-Vue — облегчённая реактивная библиотека, созданная для управления состоянием интерфейса без сложной инфраструктуры. Основу её работы составляет система реактивности, которая автоматически отслеживает зависимости между данными и DOM, обновляя отображение при изменении состояния.

В Petite-Vue каждый объект данных, на который ссылается шаблон, становится реактивным через функцию reactive. Пример:

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

После создания реактивного объекта любые изменения его свойств автоматически фиксируются и могут триггерить обновление DOM. Это достигается через наблюдателей (watchers), которые связывают шаблон с конкретными свойствами объекта.


Автоматическое отслеживание зависимостей

Основная сила Petite-Vue заключается в автоматическом отслеживании зависимостей. Когда шаблон обращается к свойству реактивного объекта, Petite-Vue регистрирует связь между этим свойством и конкретным DOM-узлом или вычисляемым выражением.

Пример:

<div pv-text="state.count"></div>
<button @click="state.count++">Увеличить</button>

Здесь свойство state.count автоматически связано с содержимым <div>. Любое изменение state.count инициирует обновление текста в DOM, без явного вызова функций перерисовки.


Вычисляемые свойства

Для сложных зависимостей используются вычисляемые свойства (computed). Они создаются с помощью функции computed и автоматически обновляются при изменении любой из зависимостей:

const doubled = computed(() => state.count * 2);

Использование в шаблоне:

<div pv-text="doubled"></div>

Важно, что вычисляемое свойство отслеживает только те данные, к которым обращается внутри функции. Если внутри функции используется state.user.age, изменение state.user.name не вызовет пересчёт doubled.


Наблюдатели (watch)

Для выполнения побочных эффектов при изменении данных используется функция watch. Она позволяет реагировать на изменения конкретного свойства:

watch(() => state.count, (newVal, oldVal) => {
  console.log(`count изменился с ${oldVal} на ${newVal}`);
});

Ключевые особенности:

  • watch регистрирует зависимость на момент выполнения функции.
  • Поддерживаются глубокие наблюдатели через опцию { deep: true }.
  • Подходит для синхронизации состояния с внешними источниками, например, LocalStorage или API.

Глубокое и поверхностное отслеживание

  • Поверхностное отслеживание фиксирует только прямые свойства объекта.

    const state = reactive({ user: { name: 'Alice', age: 25 } });
    state.user.name = 'Bob'; // не всегда триггерит обновление, если следить за state.user
  • Глубокое отслеживание позволяет автоматически фиксировать изменения вложенных объектов:

    watch(() => state.user, () => { ... }, { deep: true });

Для массивов и объектов Petite-Vue использует прокси, перехватывающие операции добавления, удаления и модификации, что обеспечивает полное отслеживание зависимостей.


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

Изменения массивов обрабатываются через методы push, pop, splice и другие. Любое действие, влияющее на длину или содержимое массива, автоматически обновляет DOM, если массив используется в шаблоне через pv-for.

const items = reactive(['яблоко', 'банан']);

items.push('вишня'); // pv-for сразу отобразит новый элемент

При работе с объектами и массивами стоит помнить: добавление нового свойства через прямое присваивание не всегда отслеживается, если объект уже создан. Для этого Petite-Vue рекомендует создавать реактивные структуры изначально с нужными ключами или использовать методы reactive и ref.


Рефы (ref) и отслеживание примитивов

Для примитивных значений используется ref. Это объект с единственным свойством value:

const count = ref(0);
count.value++; // автоматически обновит все привязки

ref удобно применять для чисел, строк, булевых значений и объектов, когда нужно отдельное управление реактивностью без создания целого объекта.


Оптимизация и контроль зависимостей

Petite-Vue строит граф зависимостей автоматически, но иногда нужно явно управлять перерисовкой:

  • Использование computed вместо прямого выражения в шаблоне уменьшает количество пересчётов.
  • Глубокие наблюдатели { deep: true } применяются только там, где это действительно необходимо, чтобы избежать лишней нагрузки.
  • Избегание ненужной вложенности реактивных объектов снижает количество триггеров обновления.

Итоговая архитектура реактивности

Система отслеживания зависимостей Petite-Vue строится вокруг трёх ключевых компонентов:

  1. Reactive objects — объекты, превращённые в реактивные через reactive.
  2. Computed properties — вычисляемые значения, автоматически отслеживающие свои зависимости.
  3. Watchers — наблюдатели, выполняющие побочные эффекты при изменении данных.

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