Design Patterns

Поговорим о компонентах дизайн-системы, в особенности о компонентах wrapper. Как создать мощную структуру компонента wrapper? В примере будем использовать поле ввода и кнопку.

Шаг 1.
Вопросы архитектуры:

Skillbox
  • Какими состояниями обладает поле ввода?
  • Где извлекаются и отправляются данные?
  • Будут ли они поддерживать собственный слой данных?
  • Нужно ли синхронизировать поля ввода с центральным хранилищем данных, таким как Vuex?

Шаг 2.
Ответы:

  • Hover, OnFocus, Error.
  • В родительском компоненте.
  • Слой данных исходит из родительского (в этом случае можно сделать по-своему).
  • Все данные синхронизируются с родительским компонентом input.

Отлично! Теперь рассмотрим простой пример компонента input.

  • Корневой label оборачивает компонент input.
  • Привязываем компонент input к $attrs (подробнее об этом позже).
  • Слушаем “$listeners” (что бы это ни было).
  • Наконец, слушаем изменения “input” и передаем событие “change” родителю.

Для VueJS компоненты были идеалистичны и присущи каждому фреймворку, управляемому компонентами. Частью утверждения “prop” являются атрибуты или “директивы”, переданные из родителя. Они не распознаются дочерним компонентом как prop и автоматически прикрепляются к root дочернего компонента. Это сбивает с толку.

Представьте, что передаете приветствие в wrapper input. Если приветствие не зарегистрировано как prop, то оно будет добавлено в качестве поля в wrapper поля ввода <label> со значением false для inheritAttrs. Чтобы предотвратить это, нужно выполнить переопределение и передать все мета-данные напрямую в компонент input. Таким образом, вы избавитесь от необходимости регистрировать КАЖДЫЙ prop в wrapper input. Однако в сущности, он проходит через wrapper естественным образом (насколько позволяет wrapper).

С помощью $listeners в Vue всплывают все события, которые компонент слушает до родителя. Таким образом, не нужно регистрировать каждый компонент вручную — это еще один отличный способ создания компонента wrapper. Целью wrapper является предоставление согласованности дизайна. Помимо этого, wrapper отвечает за пользовательскую логику. В компонент wrapper можно добавлять любое количество пользовательской логики. Получить доступ к value поля ввода можно с помощью регистрации value в качестве prop.

Wrapper input с моделью, определенной в области видимости компонента, в которой создан wrapper, а также атрибуты, которые должны быть переданы напрямую в компонент input, будут зарегистрированы согласно ожиданиям.

🚨VUE 3.0🚨

При создании базы компонента wrapper в Vue 3.0 не понадобится так много конфигурации.

Теперь компонент НАМНОГО проще использовать:

Обратите внимание на отсутствие $listeners или inheritAttrs.

Также в Vue 3.0 отсутствует автоматическое наследование атрибутов. Это означает, что $attrs автоматически включает все non-prop атрибуты без определения inheritAttrs: false.

Даже с listeners v-on напрямую компилирует в атрибуты, а @enter компилирует в on-enter с помощью v-bind="attrs".

"attrs" также включает все непереданные listeners. Помимо этого…

v-model компилируется в model-value и on-model-update с помощью v-bind="$attrs". Это означает, что больше не нужно использовать опцию model или переопределять событие input.


Перевод статьи Vaibhav Namburi: The Perfect Wrapper Components in Vue 2.6 and soon Vue 3.0