Поговорим о компонентах дизайн-системы, в особенности о компонентах wrapper. Как создать мощную структуру компонента wrapper? В примере будем использовать поле ввода и кнопку.
Шаг 1.
Вопросы архитектуры:
- Какими состояниями обладает поле ввода?
- Где извлекаются и отправляются данные?
- Будут ли они поддерживать собственный слой данных?
- Нужно ли синхронизировать поля ввода с центральным хранилищем данных, таким как 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