Рубрики
Без рубрики

Советы и трюки для создания многоразовых пользовательских интерфейсов

Советы и трюки Gabriel Colombo для создания многоразовых пользовательских интерфейсовфонфоновPhoto от Farzard Nazifiin В этой статье я хочу поделиться некоторыми советами и трюками, которые я использую во время создания нашей основной библиотеки Frontend, используя Ember.js. Не имея контакта с ним раньше, это было отличная возможность обучения. я надеюсь

Автор оригинала: FreeCodeCamp Community Member.

Габриэль Коломбо

В этой статье я хочу поделиться некоторыми советами и трюками, которые я использую при создании нашей основной библиотеки Frontend с использованием Ember.js. Не имея контакта с ним раньше, это было отличная возможность обучения. Я надеюсь, что вы, ребята, наслаждаетесь этим! Обратите внимание, что код, используемый для примера идей в статье, содержит достаточно информации, чтобы получить точку. Он также использует некоторую терминологию Ember.js, но концепции должны быть рамочными агностическими.

Цели

Чтобы проложить его просто, требования к построению библиотеки следующие:

  1. Это должно быть продуктивным.
  2. Это должно быть поддержано.
  3. Это должно быть последовательным.

Подходы

Минимизировать бизнес-логику

Одной из наиболее частых проблем, которые я сталкиваюсь с проектами, являются компонентами, которые содержат слишком много логики в них. Таким образом, выполнение задач, которые являются теоретически, из их объема.

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

Представьте, что мы создаем компонент кнопки.

Я хотел бы иметь возможность:

  • Сообщить, какой тип кнопки это – первичный или обычный
  • Сообщите контент, отображаемый внутри кнопки (значок и текст)
  • Отключить или включить кнопку
  • Выполнить некоторые действия на щелчке

Имея этот маленький контур, вытащите разные детали, участвующие в процессе построения этого компонента. Попробуйте определить, где можно было бы разместить вещи.

1 – тип и содержание являются компонентом, поэтому их можно поместить в компонентный файл.

Поскольку тип – в некоторой степени – требуется, давайте добавим проверку в случае, если значение не было предоставлено.

const type = get(this, 'type');
const types = {  primary: 'btn--primary',  regular: 'btn--regular',}
return (type) ? types[type] : types.regular;

Мне нравится отображать свойства в объекте, потому что он позволяет вещам масштабировать без особых усилий – на случай, если нам нужна кнопка опасности или что-то подобное.

2 – Состояние отключенного отключения можно найти на разных компонентах, таких как вход. Чтобы избежать повторения, это поведение может быть перемещено в модуль или любая общая структура – люди называют это Мистин Отказ

3 – действие Click можно найти в разных компонентах. Таким образом, он также может быть перемещен в другой файл и должен содержать логику внутри него – просто вызывая обратный вызов, предоставленный разработчиком.

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

Отдельный многоразовый интерфейс UI

Некоторые взаимодействия UI распространены между различными компонентами, как:

  • Включить/отключить – например. Кнопки, входы
  • Развернуть/сжать – например. Коллапс, раскрывающиеся списки
  • Показать/Скрыть – В значительной степени все

Эти свойства часто используются только для контроля визуального состояния – надеюсь.

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

/* UIStateMixin */
disable() {  set(this, 'disabled', true);
  return this;},
enable() {  set(this, 'disabled', false');
  return this;},

Каждый метод отвечает только за переключение конкретной переменной и возвращает текущий контекст для цепочки, как:

button  .disable()  .showLoadingIndicator();

Этот подход может быть продлен. Он может принимать разные контексты и контролировать внешние переменные вместо использования внутренних. Например:

_getCurrentDisabledAttr() {  return (isPresent(get(this, 'disabled')))    ? 'disabled'            /*  External parameter  */    : 'isDisabled';         /*  Internal variable   */},
enable(context) {  set(context || this, this._getCurrentDisabledAttr(), false);
  return this;}

Абстрагированные базовые функции

Каждый компонент содержит определенные процедуры. Эти процедуры должны выполняться независимо от цели компонента. Например, проверка обратного вызова перед его запуском.

Эти методы по умолчанию также могут быть перемещены в свои собственные смесины, например:

/* BaseComponentMixin */
_isCallbackValid(callbackName) {  const callback = get(this, callbackName);    return !!(isPresent(callback) && typeof callback === 'function');},
_handleCallback(callback, params) {  if (!this._isCallbackValid(callback)) {    throw new Error(/* message */);  }
  this.sendAction(callback, params);},

А затем включен в компоненты.

/* Component */
onClick(params) {  this._handleCallback('onClick', params);}

Это сохраняет вашу базовую архитектуру последовательную. Это также позволяет расширить и даже интеграцию со сторонним программным обеспечением. Но, пожалуйста, не будь философство abstracter Отказ

Сочинение компонентов

Избегайте перезаписи функциональность столько, сколько сможете. Специализация может быть достигнута. Это можно сделать с помощью состава и группировки. А также настроить меньшие компоненты вместе для создания новых компонентов.

Например:

Base components: Button, dropdown, input.
Dropdown button => button + dropdownAutocomplete => input + dropdownSelect => input (readonly) + dropdown

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

Разделение опасений на самом лучшем.

Расщепляющиеся проблемы

При составлении более сложных компонентов существует возможность расщепления. Вы можете разделить опасения между разными частями компонента

Допустим, мы создаем компонент выбора.

{{form-select binding=productId items=items}}
items = [  { description: 'Product #1', value: 1 },  { description: 'Product #2', value: 2 }]

Внутри у нас есть простой входной компонент и раскрывающийся.

{{form-input binding=_description}}
{{ui-dropdown items=items onSelect=(action 'selectItem')}}

Наша главная задача – представить описание пользователю, но оно не имеет значения для нашего приложения – значение делает.

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

Эта концепция может быть применена к компонентам, где связанное значение должно быть преобразовано, как число, автозаполнение или поле выбора. DatePickers также могут реализовать это поведение. Они могут разоблачить дату перед обновлением связанной переменной при представлении значения маскировки пользователю.

Риски становятся выше, чем преобразования увеличиваются в сложности. Путем чрезмерной логики или необходимость поддержки событий – так что думайте, прежде чем реализовать этот подход.

Предустановки против новых компонентов

Иногда необходимо оптимизировать компоненты и услуги, чтобы облегчить развитие. Они доставляются в виде предустановок или новых компонентов.

Предустановки являются параметрами. При информировании они устанавливают заранее определенные значения на компонент, упрощая его декларацию. Однако новые компоненты обычно являются более специализированными версиями базовых компонентов.

Тяжелая часть состоит в том, чтобы знать, когда реализовать предустановки или создавать новые компоненты. При принятии этого решения я использую следующие рекомендации:

Когда создавать пресеты

1 – Повторяющиеся узоры использования

Есть времена, когда определенный компонент повторно используется в различных местах с одинаковыми параметрами. В этих случаях я люблю оказывать предустановки по новым компонентам, особенно когда базовый компонент имеет чрезмерное количество параметров.

/* Regular implementation */
{{form-autocomplete    binding=productId    url="products"            /*   URL to be fetched         */    labelAttr="description"   /*   Attribute used as label   */    valueAttr="id"            /*   Attribute used as value   */    apiAttr="product"         /*   Param sent on request     */}}
/* Presets */
{{form-autocomplete    preset="product"    binding=productId}}

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

/* Naive implementation of the presets module */
const presets = {  product: {    url: 'products',    labelAttr: 'description',    valueAttr: 'id',    apiAttr: 'product',  }, }
const attrs = presets[get(this, 'preset')];
Object.keys(attrs).forEach((prop) => {  if (!get(this, prop)) {    set(this, prop, attrs[prop]);  }});

Этот подход снижает знания, необходимые для настройки вашего компонента. Одновременно содействует обслуживанию, позволяя вам обновлять значения по умолчанию в одном месте.

2 – Базовый компонент слишком сложный

Когда базовый компонент, который вы бы использовали для создания более конкретного компонента, принимают слишком много параметров. Таким образом, создание его сгенерирует некоторые проблемы. Например:

  • Вам придется ввести большинство – если не все – параметры из нового компонента к базовому компоненту. Поскольку все больше и больше компонентов вытекают из него, любые обновления на базовом компонент будут отражать огромное количество изменений. Таким образом, ведущий к более высокой заболеваемости.
  • По мере создания больше компонентов, тем сложнее он попадает в документу и запомнить различные нюансы. Это особенно верно для новых разработчиков.

Когда создавать новые компоненты

1 – Расширение функциональности

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

/* Declaration */
{{ui-button-dropdown items=items}}
/* Under the hood */
{{#ui-button onClick=(action 'toggleDropdown')}}  {{label}}   {{/ui-button}}
{{#if isExpanded}}  {{ui-dropdown items=items}}{{/if}}

Приведенный выше примера использует компонент кнопки. Это расширяет его макет для поддержки фиксированного значка при включении раскрывающегося компонента и его состояние видимости.

2 – Украшение параметров

Есть еще одна возможная причина создания новых компонентов. Это когда необходимо контролировать доступность параметра или украсить значения по умолчанию.

/* Declaration */
{{form-datepicker onFocus=(action 'doSomething')}}
/* Under the hood */
{{form-input onFocus=(action '_onFocus')}}
_onFocus() {  $(this.element)    .find('input')    .select();                 /* Select field value on focus */
  this._handleCallback('onFocus'); /* Triggers param callback */}

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

Внутри, вместо того, чтобы пройти обратный вызов прямо к базовому компоненту, он передает внутреннюю функцию. Это выполняет определенную задачу (выбирая значение поля), а затем вызывает прилагаемый обратный вызов.

Он не перенаправляет все параметры, принимаемые базовым входным компонентом. Это помогает контролировать объем определенных функций. Это также позволяет избежать ненужных валидаций.

В моем случае событие OnBlur было заменено другим событием – Onchange. Это триггеры, когда пользователь либо заполняет поле или выбирает дату на календаре.

Заключение

При строительстве ваших компонентов рассмотрим свою сторону, а также тот, кто использует этот компонент в своей повседневной жизни. Таким образом, все выигрывают.

Кроме того, не стыдно попросить обратную связь. Вы всегда найдете то, на что можно работать.

Еще больше заточить свои навыки программного обеспечения навыки, я рекомендую использовать Эрик Эллиотт серия « сочинение программного обеспечения». Это круто!

Ну, я надеюсь, что вам понравилось статью. Пожалуйста, возьмите эти концепции, превратитесь в свои идеи и поделитесь этим с нами!

Кроме того, не стесняйтесь добраться до меня в Twitter @gcolombo_ ! Я хотел бы услышать ваше мнение и даже работать вместе.

Спасибо!

Оригинал: “https://www.freecodecamp.org/news/tips-tricks-for-creating-reusable-ui-components-2b1452147bda/”