Другой пример: настраиваемые элементы управления, такие как раскрывающиеся списки, средства выбора времени или свойства автозаполнения, очень сложны, и необходимо учитывать множество граничных сложностей. Хотя существует множество библиотек, которые хорошо справляются с этой сложностью, они также имеют недостаток, заключающийся в том, что такие компоненты нельзя стилизовать.
В качестве примера возьмем следующий элемент управления вводом меток:
Этот компонент имеет несколько интересных особенностей:
- Вы не можете добавлять повторяющиеся теги
- Пустые теги не допускаются
- Автоматически удалять пробелы с обеих сторон содержимого тега
- Нажмите Enter, чтобы сохранить метку.
- Нажмите на символ x, чтобы удалить метку
Если вам нужно использовать такой компонент в своем проекте, использование его в виде библиотеки и удаление логики, безусловно, сэкономит много времени и усилий.
Но что, если вам нужен другой стиль в это время?
Следующий компонент имеет то же поведение, что и предыдущий компонент, но макет значительно отличается:
Комбинируя css и параметры конфигурации, можно попытаться поддерживать эти макеты в одном компоненте, но очевидно, что это не очень хороший способ, в случае, если однажды вам понадобится другой макет, вам придется снова изменить этот компонент, уничтожив закрытый компонент, который может легко привести к другим проблемам.
Ввиду вышеизложенной ситуации позвольте представить один из самых важных пунктов этой статьи.
Слоты с ограниченной областью действия
В Vue.js слоты — это элементы-заполнители в компонентах, которые заменяются содержимым, переданным от родительского компонента/потребителя.
Обычные слоты похожи на передачу фрагмента текста html в компонент, а слоты с ограниченной областью действия похожи на передачу функции обратного вызова компоненту, который может получать данные и возвращать HTML.
Передайте параметры родительскому компоненту, добавив реквизиты к элементу слота в дочернем компоненте. родительский компонент через деструктурированиеdestructuring slot-scopeДанные атрибута, полученные внутри, чтобы получить эти параметры.
Вот тот, который предоставляет атрибут слота с областью действия для каждого элемента списка.LinksListкомпоненты и через:linkреквизиты передают данные каждого элемента обратно родительскому элементу.
:linkprop добавлен к элементу слота в компоненте LinksList, компонент родительского элемента теперь может передаватьslot-scopeПолучите доступ к этим данным и используйте их в своем собственном слотовом модуле.
Тип свойства слота
Вы можете передать в слот любой тип, но я считаю наиболее полезным использовать один из следующих 3 типов данных.
Данные
Простейшими типами реквизитов слота являются типы данных: строки, числа, логические значения, массивы, объекты и т. д.
В нашем примере компонента списка ссылокlinkПримером типа data prop является объект с некоторыми свойствами.
Действия
Атрибут действия — это функция, предоставляемая дочерним компонентом, и родительский компонент может вызвать эту функцию, чтобы вызвать определенные действия в дочернем компоненте.
Например, мы можем передать родительский компонент abookmarkметод, который используется для добавления данной ссылки в закладки.
Привязки
Bindings — это набор свойств или событий прослушивания с использованиемv-bindилиv-on, привязанный к определенному элементу.
Они полезны, когда вы хотите инкапсулировать подробности о том, как взаимодействовать с данным элементом.
Например, мы предоставляемbookmarkButtonAttrsсвязывать иbookmarkButtonEventsПривязки используются для перемещения этих деталей к самому компоненту, вместо того, чтобы позволять потребляющему компоненту передавать их самостоятельно.v-showинструкция и@clickОбрабатывает логику кнопок для добавления в закладки.
Renderless Components
объяснение имени: Компоненты без рендеринга, дословно переводится как компоненты без рендеринга, я предпочитаю называть их функциональными компонентами (на которые ссылается название в реакции, далее в совокупности именуемые функциональными компонентами).
Функциональный компонент — это компонент, который не отображает HTML-текст.
Вместо этого он только управляет состоянием и поведением, предоставляя слот с заданной областью для родительских или потребляющих компонентов, чтобы они могли сами управлять визуализируемым содержимым.
Функциональный компонент отображает именно то, что вы ему передаете, без каких-либо дополнительных элементов.
Производительность и поведение разделительного слоя
Поскольку функциональные компоненты имеют дело только с состоянием и поведением, они не принимают никаких решений по дизайну и компоновке.
Это означает, что если вы можете найти способ убрать интересное поведение, такое как наша функциональность ввода метки, из компонента пользовательского интерфейса, вы можете повторно использовать этот функциональный компонент для реализации макета любого компонента ввода метки.
Ниже представлены все компоненты ввода меток, но на этот раз они поддерживаются функциональным компонентом.
Базовая структура функциональных компонентов
Функциональные компоненты предоставляют только слот с заданной областью, где потребители могут предоставить весь модуль, который они хотят отобразить.
Скелет базового функционального компонента выглядит так:
Любой родительский компонент/потребитель может уничтожить его в своем собственном шаблоне.slot-scopeсерединаexamplePropиспользовать.
Практический вариант использования
Давайте создадим функциональную версию элемента управления вводом метки с нуля.
Сначала нам нужно создать пустой компонент без рендеринга без слотов,
и статический родительский компонент без какого-либо взаимодействия, который затем передается в слот дочернего компонента,
slot-scopeВыставили наш макет для завершения этого компонента.
список тегов
Во-первых, мы заменяем статический список динамическим списком.
Этот компонент ввода метки является пользовательским элементом управления формы, и этооригинальный примерТо же самое, эти теги должны быть в родительском компоненте и проходитьv-modelпривязать к компоненту.
Сначала мы добавляем свойство value к функциональному компоненту и передаем его в слот, называемый тегами.
v-modelинструкция, отslot-scopeПолучить теги из , затем сделать用v-forинструкции по их повторению.
убрать тэг
Затем, когда нажата кнопка X, удалите метку.
В функциональных компонентах мы добавимremoveTagметод и передать его как атрибут слота родительскому элементу.
@clickсобытие, это событие можно вызвать в текущей вкладкеremoveTagметод.
Нажмите Enter, чтобы добавить тег
Добавление новых тегов сложнее, чем в предыдущих двух примерах.
Чтобы понять почему, давайте сначала посмотрим, как реализованы традиционные компоненты.
v-modelПривяжите это свойство к входу.
Как только пользователь нажимает ввод, пока тег действителен, мы добавляем его в массив списка, а затем очищаем значение ввода.
Вопрос здесь в том, как мы передаем слот с прицеломv-modelсвязывать.
Что ж, если вы хорошо знаете Vue, вы должны знатьv-modelПо сути, это синтаксический сахар, который отвечает за привязку атрибута value к пропу с именем value, и в то же время, когда его событие ввода срабатывает, новое значение выбрасывается через пользовательское событие ввода.
- добавить компонент
newTagатрибут данных - возвращает привязку к
:valueизnewTagобязательное свойство - вернуть привязку
@keydown.enterИспользуется для добавления меток и привязок@inputСвойство привязки события, используемое для обновления метки
Явное добавление новых тегов
В нашем текущем макете пользователь добавляет новую метку, вводя элемент ввода и нажимая клавишу ввода. Но также легко подумать, что некоторые пользователи хотели бы иметь возможность предлагать щелкнуть кнопку добавления, чтобы добавить теги.
Достичь этого очень просто, нам просто нужно передать область действия слотаaddTagссылка на метод.
Потребителям нужно деконструировать только те свойства, которые им действительно нужны, поэтому, если вы предоставляете свойства, которые они могут не использовать, они не будут стоить дорого.
запустить демонстрацию
Это функциональный компонент, который мы создали на данный момент:
изменить макет
Теперь, когда у нас есть функциональный компонент с помеченным элементом управления вводом, мы можем легко реализовать альтернативные макеты, написав любой HTML-код и применив предоставленные свойства слота в нужных местах.
Вот макет с накоплением, который мы реализовали с нуля, используя наш новый функциональный компонент.
Создайте свой собственный обернутый компонент
Увидев так много примеров, вы можете подумать: «Вау, мне нужно писать так много html каждый раз, когда мне нужна другая форма компонента лейбла», да, вы правы.
Всякий раз, когда вам нужен компонент ввода метки, вам нужно много писать.
Это легко исправить: создайте свой собственный обернутый компонент!
<tags-input>как выглядит компонент
еще безумнее
Как только вы поймете, что компонент может отвечать за предоставление данных без какого-либо рендеринга, тогда не будет ограничений для поведения, моделируемого компонентами.
Например, вот метод, который использует URL-адрес в качестве атрибута для получения данных json из этого URL-адреса и передачи данных ответа родительскому компоненту.fetch-dataКомпоненты:
в заключении
Разделение компонента на компонент представления и функциональный компонент — очень полезный шаблон для упрощения повторного использования кода, но не стоит делать это каждый раз.
Рассмотрите возможность использования этого режима, если:
- Вы собираетесь создать библиотеку и хотите, чтобы пользователи могли настраивать внешний вид компонентов.
- В вашем проекте много компонентов с похожими функциями, но разными макетами.
Если вы работаете над компонентом, который выглядит одинаково в любой ситуации, не идите по этому пути. В этом случае может быть лучше и проще написать все, что вам нужно, в одном компоненте.
Кроме того, разделение кода представления и бизнес-логики является лишь средством уменьшения связанности кода и, таким образом, повышения надежности кода.Глубокий уровень заключается в том, что компоненты должны соответствовать идее высокой связанности и низкой связанности.Другие средства, соответствующие эта идея также нравитсяИнверсия контроля(IOC), модель публикации-подписки и т. д., я думаю, чем больше вы будете писать код позже, тем больше вы должны развивать это осознание.В противном случае просто напишите бизнес-код и напишите код, отвечающий требованиям, и улучшение будет быть медленнее.
Перевод статьи не полностью переведен в соответствии с оригинальным текстом.Чтобы лучше понять его, я добавил немного своего понимания.Если вам понравилась моя статья, пожалуйста, поставьте лайк, чтобы выразить поддержку, или поделитесь ею с друзьями .