Ref-ссылки на дочерние компоненты

В Slim.js ref используется для получения прямого доступа к DOM-элементам или дочерним компонентам внутри родительского компонента. Это особенно полезно, когда требуется программно управлять поведением дочернего компонента или взаимодействовать с его методами и свойствами.


Основы использования ref

Для привязки ссылки к дочернему компоненту в шаблоне используется атрибут ref. В отличие от обычного селектора querySelector, ref гарантирует прямой доступ к экземпляру компонента после его инициализации.

class ChildComponent extends Slim {
  get template() {
    return `<div>Дочерний компонент</div>`;
  }

  someMethod() {
    console.log('Метод дочернего компонента вызван');
  }
}

ChildComponent.define('child-component');

class ParentComponent extends Slim {
  get template() {
    return `
      <child-component ref="childRef"></child-component>
      <button @click="callChildMethod">Вызвать метод дочернего компонента</button>
    `;
  }

  callChildMethod() {
    this.refs.childRef.someMethod();
  }
}

ParentComponent.define('parent-component');

Ключевые моменты:

  • ref="childRef" создаёт ссылку на экземпляр ChildComponent в объекте this.refs родителя.
  • Объект this.refs автоматически формируется после того, как шаблон компонента смонтирован.
  • Методы дочернего компонента доступны напрямую через this.refs.childRef.

Автоматическое управление ссылками

Slim.js обеспечивает автоматическое обновление refs при динамическом добавлении или удалении компонентов в шаблоне. Это значит, что ссылки остаются актуальными даже при изменении DOM через условные рендеры или циклы.

class ParentComponent extends Slim {
  isVisible = true;

  get template() {
    return `
      ${this.isVisible ? `<child-component ref="childRef"></child-component>` : ''}
      <button @click="toggleChild">Переключить компонент</button>
      <button @click="callChildMethod">Вызвать метод</button>
    `;
  }

  toggleChild() {
    this.isVisible = !this.isVisible;
    this.update();
  }

  callChildMethod() {
    if (this.refs.childRef) {
      this.refs.childRef.someMethod();
    } else {
      console.log('Дочерний компонент отсутствует');
    }
  }
}

ParentComponent.define('parent-component');

Особенности:

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

Ref для элементов DOM внутри дочернего компонента

ref может быть применён не только к компонентам, но и к обычным DOM-элементам. В таком случае объект refs содержит ссылки на элементы, а не на экземпляры компонентов.

class FormComponent extends Slim {
  get template() {
    return `
      <input type="text" ref="inputField" />
      <button @click="focusInput">Фокус на поле</button>
    `;
  }

  focusInput() {
    this.refs.inputField.focus();
  }
}

FormComponent.define('form-component');

Преимущества:

  • Прямой доступ к DOM без необходимости использовать querySelector.
  • Удобно для управления фокусом, прокруткой, классами и стилями элементов.

Ref в списках и циклах

При использовании each для генерации элементов, Slim.js позволяет привязать ref к каждому элементу с уникальным ключом. Это создаёт объект ссылок, где ключи соответствуют идентификаторам элементов.

class ListComponent extends Slim {
  items = ['Элемент 1', 'Элемент 2', 'Элемент 3'];

  get template() {
    return `
      ${this.items.map((item, index) => `<div ref="item${index}">${item}</div>`).join('')}
      <button @click="highlightSecond">Выделить второй элемент</button>
    `;
  }

  highlightSecond() {
    this.refs.item1.style.backgroundColor = 'yellow';
  }
}

ListComponent.define('list-component');

Примечания:

  • Каждому элементу присваивается уникальная ссылка.
  • refs удобен для массового управления динамическими элементами без обращения к DOM напрямую.

Ограничения и особенности

  1. Асинхронная инициализация: ссылки становятся доступны только после того, как компонент инициализируется и смонтируется. Попытка доступа к refs в конструкторе приведёт к undefined.
  2. Нельзя использовать один ref для нескольких элементов без уникализации. В противном случае будет храниться только последний элемент.
  3. Удаление компонентов: Slim.js автоматически очищает refs, но при необходимости можно вручную удалить или обнулить ссылку для контроля памяти.

Итоговое применение

ref в Slim.js обеспечивает безопасное и удобное взаимодействие с дочерними компонентами и DOM-элементами. Он упрощает:

  • вызов методов дочерних компонентов,
  • управление фокусом и стилями,
  • работу с динамически создаваемыми элементами и списками.

Правильное использование refs повышает читаемость кода и делает компоненты более управляемыми, избегая хаотичных манипуляций с DOM.