Интеграция с MobX

Slim.js — легковесная библиотека для создания реактивных веб-компонентов, ориентированная на простоту и высокую производительность. Для управления состоянием и реактивностью часто используется MobX, обеспечивающий автоматическое обновление интерфейса при изменении данных. Интеграция этих двух библиотек позволяет создавать динамичные компоненты с минимальными усилиями.


Подключение MobX и Slim.js

Для начала необходимо установить необходимые зависимости через npm:

npm install slim-js mobx

Импорт модулей в проект:

import Slim from 'slim-js';
import { observable, autorun } from 'mobx';
  • Slim — основной конструктор веб-компонентов.
  • observable — функция MobX, делающая объект реактивным.
  • autorun — функция MobX, автоматически выполняющая код при изменении реактивных данных.

Создание реактивного состояния

Состояние приложения определяется с помощью observable. Например:

const appState = observable({
  count: 0,
  message: 'Привет, Slim.js с MobX!'
});

Любое изменение appState.count или appState.message может автоматически инициировать обновление пользовательского интерфейса.


Реактивное связывание с компонентами Slim.js

Slim.js позволяет определять свойства компонента, которые обновляются при изменении данных. При использовании MobX необходимо подписаться на изменения с помощью autorun:

class CounterComponent extends Slim {
  static get observedAttributes() {
    return ['count', 'message'];
  }

  count = 0;
  message = '';

  onBeforeCreated() {
    autorun(() => {
      this.count = appState.count;
      this.message = appState.message;
    });
  }

  get template() {
    return `
      <div>
        <h1>${this.message}</h1>
        <p>Счётчик: ${this.count}</p>
        <button oncl ick="this.increment()">Увеличить</button>
      </div>
    `;
  }

  increment() {
    appState.count += 1;
  }
}

Slim.define('counter-component', CounterComponent);

Особенности подхода:

  • autorun следит за изменением любых реактивных свойств.
  • Свойства компонента обновляются автоматически, что обеспечивает реактивный рендеринг.
  • Любые действия пользователя могут изменять состояние через MobX, и интерфейс синхронизируется без прямого вызова update().

Обновление сложных структур данных

MobX поддерживает глубокую реактивность объектов и массивов. Для примера:

const todoStore = observable({
  todos: [
    { id: 1, text: 'Изучить Slim.js', done: false },
    { id: 2, text: 'Интегрировать с MobX', done: false }
  ]
});

class TodoComponent extends Slim {
  todos = [];

  onBeforeCreated() {
    autorun(() => {
      this.todos = todoStore.todos.map(todo => ({ ...todo }));
    });
  }

  get template() {
    return `
      <ul>
        ${this.todos.map(todo => `
          <li>
            <input type="checkbox" ${todo.done ? 'checked' : ''} oncl ick="this.toggleTodo(${todo.id})">
            ${todo.text}
          </li>
        `).join('')}
      </ul>
    `;
  }

  toggleTodo(id) {
    const todo = todoStore.todos.find(t => t.id === id);
    if (todo) todo.done = !todo.done;
  }
}

Slim.define('todo-component', TodoComponent);
  • Реактивность сохраняется при изменении элементов массива.
  • Копирование объектов в autorun предотвращает прямое связывание состояния с шаблоном, минимизируя неожиданные побочные эффекты.
  • Любые изменения todoStore.todos автоматически обновляют DOM.

Работа с computed и действиями MobX

MobX позволяет использовать computed для вычисляемых значений и action для структурирования изменений:

import { computed, action } from 'mobx';

const appState = observable({
  count: 0,
  increment: action(function() {
    this.count += 1;
  }),
  get double() {
    return this.count * 2;
  }
});

В компоненте Slim.js можно использовать computed значения напрямую:

autorun(() => {
  this.count = appState.count;
  this.doubleCount = appState.double;
});

action обеспечивает централизованное управление изменениями состояния, что повышает предсказуемость поведения приложения.


Рекомендации по оптимизации

  • Использовать autorun для реактивного связывания только внутри onBeforeCreated или onCreated.
  • Для больших массивов и списков применять map с уникальными ключами для предотвращения ненужных перерисовок.
  • Избегать прямой модификации DOM вне Slim.js — все изменения должны проходить через реактивные свойства.
  • Разделять состояние на несколько observable объектов для локальной оптимизации обновлений.

Примеры расширенных интеграций

  1. Фильтрация и сортировка: реактивные массивы MobX позволяют применять вычисления, и изменения автоматически отображаются в компоненте.
  2. Вложенные компоненты: состояние может передаваться через свойства, создавая цепочку реактивности без дублирования данных.
  3. Асинхронные операции: runInAction позволяет безопасно изменять состояние после промисов или fetch-запросов.

Использование Slim.js совместно с MobX открывает возможность создавать легкие, динамичные и высокореактивные веб-компоненты, которые автоматически синхронизируют интерфейс с состоянием приложения, минимизируя ручное управление DOM и упрощая архитектуру приложения.