Введение
При разработке страницы регистрации необходимо учитывать несколько моментов. Что касается знака дизайна, пользователь должен легко понять, какую информацию ввести в каждое поле. Если информация должна быть в определенном формате, лучше всего дать пользователю подсказку о том, что он должен делать. На стороне обработки формы проверка гарантирует, что форма не будет отправлена на сервер с недопустимой информацией. Пользователь может быть уведомлен о достоверности информации либо при вводе, либо при отправке. При сообщении об ошибках, чем более конкретна ошибка, тем раньше пользователь поймет, что пошло не так.
Достижение всего этого требует большой работы. Мы можем упростить процесс внедрения с помощью Одом. Odom - это JavaScript-фреймворк для создания пользовательских интерфейсов. Это вторая часть серии Знакомство с Одом. В первом выпуске The Open UI Framework были рассмотрены основные возможности Odom. В этом эпизоде мы увидим Одом в действии, создав одностраничное приложение (SPA). Приложение будет содержать раздел регистрации. Раздел регистрации будет содержать форму для регистрации. На картинке ниже показан снимок приложения (на широких экранах).
Мы сосредоточимся на следующих темах:
- Разметка
- Стили
- "События"
- Динамические данные
Репо для приложения опубликовано на GitHub. Живая демонстрация опубликована на Netlify. Вы можете клонировать или скачать репо, если хотите. Однако в эту статью я собираюсь включить весь код и дать инструкции по созданию проекта.
Файловая структура
Мы собираемся использовать следующую файловую структуру для приложения:
. └── odom-signup/ ├── src/ │ ├── assets/ │ │ └── index.css │ ├── components/ │ │ ├── alert-message.js │ │ ├── app.js │ │ ├── confirmation-message.js │ │ ├── form.js │ │ ├── input-group.js │ │ └── signup.js │ └── index.js └── index.html
Создайте файловую систему, как показано выше, используя пустые файлы. Мы заполним все файлы позже.
Создание компонентов
Для простоты мы будем использовать CDN для создания приложения. Деструктуризация будет использоваться для получения методов из window
объекта window.odom
. Это упростит вам преобразование проекта, если вы предпочитаете работать с менеджерами пакетов, такими как NPM. Следующий код демонстрирует, как можно заменить деструктурирующие присваивания операторами импорта.
Мы будем называть все экспорты в модулях в /odom-signup/src/components
компонентами, поскольку они являются самодостаточными объектами. Однако некоторые из модулей будут экспортировать функции, возвращающие узлы DOM, вместо экземпляра компонента, предлагаемого Odom. Причины этого были указаны в первом эпизоде.
Я разделю некоторые модули на несколько фрагментов кода, чтобы сделать код более читабельным.
Приложение
Корневым компонентом нашего приложения будет Приложение. Это компонент, который мы собираемся визуализировать в DOM. Мы создадим компонент в модуле at/odom-signup/src/components/app.js
. Вставьте в файл следующий код:
В модуль импортирован компонент Регистрация. Метод createComponent
получен из odom
. markup
содержит два элемента. Корневой элемент - это div
, а внутренний элемент имеет атрибут odom-node
, установленный на Signup
, который относится к компоненту, который мы импортировали. Замените комментарий (/* styles */
) в литерале шаблона для переменной styles
следующим кодом CSS:
Селектор :scope
выбирает корневой элемент компонента. В :scope
мы объявляем переменные CSS для цветовой темы и разделителей (используемых для полей, отступов и т. Д.). Остальная часть CSS устанавливает ширину, минимальную высоту, семейство шрифтов и цвет текста компонента.
Давайте посмотрим, что делает каждая из функций в модуле.
App
: Конструктор для компонента. В Odom конструктор - это функция, которая возвращает экземпляр компонента, узла DOM, разметки или текста. При вызовеApp
вернет экземплярComponent
, который также является возвращаемым значениемcreateComponent
. Использование заглавных букв в имени конструктора не обязательно. Мы будем использовать это как условность. Мы также будем начинать имена экземпляров компонентов со строчных букв. Вы не можете использовать ключевое словоnew
для вызова конструкторов Odom, как встроенных конструкторов JavaScript.createComponent
: Создает компонент. Параметр - это объект с тремя свойствами.markup
будет использоваться для создания элемента DOM для компонента.styles
будет использоваться для стилизации компонента. У объектаutils
есть одно свойство,nodes
, которое используется для предоставления ресурсов узла. Итак, значениеSignup
для атрибутаodom-node
в разметке относится кutils.nodes.Signup
.
Зарегистрироваться
Регистрация - это единственный раздел приложения. Он будет обрабатывать отправку формы и сообщение об ошибке или успешной отправке. Поместите следующий код в модуль по адресу /odom-signup/src/components/signup.js
:
В модуль мы импортируем компоненты Form и ConfirmationMessage. Мы также получаем методы createComponent
и replaceNode
из odom
. Значение form
атрибута odom-src
в markup
относится к экземпляру Form
. Значение form
не пишется с заглавной буквы, потому что оно относится к экземпляру компонента, а не к самому компоненту. Медиа-запрос в styles
устанавливает заполнение поверх компонента в окнах с шириной не менее 576px
. Обратите внимание, что мы использовали переменную --spacer-xl
, которая была объявлена в приложении. Все компоненты в Odom наследуют стили от своих предков.
Давайте посмотрим, что делает каждая функция в модуле:
Signup
: конструктор узла. Внутри функции мы создаем компонент, используем его и возвращаем узел DOMsignup.scope
. Мы возвращаем узел вместо компонента, потому что интерфейс компонента больше не нужен.onvalid
: отправляет форму, если все введенные данные действительны. Если форма была успешно отправлена, отображается подтверждающее сообщение. МетодreplaceNode
используется для замены формы наconfirmationMessage
. Если отправить форму не удалось, вызываетсяform.onSignupFail
, чтобы сообщить пользователю, что он не был зарегистрирован из-за ошибки.createComponent
: используется для создания компонента. Свойствоcomponents
параметра предоставляет ресурсы компонента, указанные в разметке.sendForm
: отправляет форму на сервер. Функция имитирует процесс отправки на сервер. Он возвращается раньше времени с обещанием, которое превращается в макет объекта ответа. Удаление оператора return оставляет с кодом, который вы можете использовать для отправки формы на реальный сервер.
Обратите внимание, что мы передали onvalid
в Form
как опору. В следующем разделе мы увидим, как onvalid
используется в Form
.
Форма
Форма инициирует отправку формы. Он также сообщает об ошибках при проверке ввода и отправке формы. Поместите следующий код в модуль по адресу /odom-signup/src/components/form.js
:
В модуль мы импортируем компоненты AlertMessage
и InputGroup
. Замените комментарий в значении markup
следующим HTML-кодом:
Значения атрибута odom-src
в section
элементах относятся к экземплярам компонентов.
Замените комментарий в значении стилей следующим кодом CSS:
Селектор > *:not(footer)
эквивалентен :scope > *:not(footer)
. Медиа-запрос устанавливает границу и фиксированную ширину для компонента в окнах шириной не менее 576px
.
Замените пустой объект для props
следующим кодом:
Объект props
содержит реквизиты для всех экземпляров InputGroup
. Ниже приведены цели каждого свойства для props каждого экземпляра:
type
: Тип входного элемента.name
: имя элемента ввода, установленное с помощью атрибутаname
.label
: текстовое содержимое для метки каждой группы ввода.pattern
: шаблон, используемый для проверки входных значений.instruction
: Инструкция по формату информации, ожидаемой от пользователя.errorMessage
: сообщение, отображаемое, если ввод неверен.successMessage
: сообщение отображается, если введенные данные действительны.
Давайте посмотрим на назначение функций, используемых в модуле:
Form
: конструктор компонента.onsubmit
: прослушиватель событияsubmit
. Он проверяет, все ли введенные данные действительны. Если введенные данные действительны, он инициирует процесс отправки, вызываяonvalid
, опору из Регистрация. Он также отключает кнопку отправки, чтобы пользователь не нажимал на нее, пока отправка еще продолжается. Он удаляет атрибутname
из элемента для подтверждения пароля, чтобы значение элемента не отправлялось с формой на сервер. Если какой-либо из входных данных недействителен, он показывает сообщение об ошибке, вызываяonerror
.onerror
: отображает сообщение об ошибке при вызовеalertMessage.show
.onSignupFail
: отображает сообщение об ошибке, если произошла ошибка регистрации. Он также включает кнопку отправки, чтобы пользователь мог повторить попытку.password.addObserver
: используется для добавления наблюдателя за изменениями входного значения в компонентеInputGroup
. Посколькуpassword
является экземпляромInputGroup
, этот метод используется для наблюдения за изменениями пароля. Обратите внимание, чтоpattern
(вprops
) дляconfirmPassword
совпадает сpassword
. Мы хотим, чтобы пользователь подтвердил свой пароль, введя его повторно. Наблюдатель используется для обновления шаблона дляconfirmPassword
, чтобы он соответствовал паролю. Он также устанавливает для допустимостиconfirmPassword
значение false, чтобы предотвратить отправку пользователем неверного пароля подтверждения, если они редактируют пароль после ввода пароля подтверждения.createComponent
: используется для создания компонента. Свойствоprops
определяет свойства компонента. На указанные таким образом реквизиты можно ссылаться в разметке и в конечном итоге они попадут в интерфейс компонента. В этом случае методonSignupFail
используется регистрацией через интерфейс. СвойствоeventListeners
параметра сопоставляет селектор CSS:scope
с массивом, содержащим объект события. Селектор используется для выбора элементов, к которым мы хотим применить прослушиватели событий, которые в данном случае являются корневым элементом компонента. Массив может содержать сколько угодно объектов событий. Свойствоtype
указывает тип события, которое мы хотим прослушать. Свойствоlistener
указывает слушателя для события.
AlertMessage
Компонент AlertMessage обрабатывает отображение сообщений об ошибках в форме. Поместите следующий код в модуль по адресу /odom-signup/src/components/alert-message.js
:
markup
содержит корневой элемент и его единственный дочерний элемент. Класс hide
установлен, чтобы по умолчанию скрыть предупреждающее сообщение. Селектор :scope.hide
в styles
выбирает корневой элемент, если он имеет класс hide
. Функции служат для следующих целей:
AlertMessage
: конструктор для компонента.show
: показать предупреждающее сообщение.createComponent
: Создает компонент. Свойствоprops
в параметре используется для добавленияshow
к интерфейсу компонента.
InputGroup
InputGroup получает вводимые пользователем данные и выполняет проверку. Поместите приведенный ниже код в модуль по адресу /odom-signup/src/components/input-group.js
:
markup
содержит section
в качестве корневого элемента. label
указывает, что пользователь должен ввести. Значение @props.inputID
относится к значению, установленному в props
, свойству параметра createComponent
(подробнее об этом позже). Атрибут odom-text
из span
внутри label
указывает, что элемент будет заменен текстом. Обратите внимание, что у элемента input
нет атрибутов. Мы установим атрибуты позже. Это связано с тем, что элемент input имеет несколько атрибутов, и установка их непосредственно в markup
затруднит чтение markup
.
Замените комментарий в значении styles
следующим кодом CSS:
Давайте посмотрим, что делает каждая функция в модуле:
InputGroup
: конструктор компонента.updateValue
: используется для обновления значения ввода в компоненте. Значение обновляется каждый раз, когда пользователь изменяет значение в поле ввода.updateValidity
: обновляет действительность ввода. Обновление выполняется каждый раз, когда пользователь меняет ввод.updateMessage
: обновляет сообщение проверки. Если ввод неверен, сообщение будет зеленого цвета. В противном случае сообщение будет красным.hasValidValue
: Проверяет, действителен ли ввод. Он также запускает обновление цвета границы, вызываяupdateInputBorder
.updateInputBorder
: обновляет границу поля ввода. Если ввод неверен, граница будет окрашена в красный цвет. В противном случае он будет окрашен в серый цвет - цвет по умолчанию.props.addObserver
: добавляет наблюдателя для входного значения. Каждый раз, когда значение изменяется, наблюдатель вызывается с новым значением.props.setValidity
: Устанавливает действительность входного значения. Это используется в интерфейсе компонента.createComponent
: Создает компонент. Функции принимаютoptions
в качестве параметра.
Свойство props
параметра options
используется для установки свойств интерфейса и предоставления значений, на которые можно ссылаться в markup
. В разметке значение @props.inputID
относится к props.inputID
. Свойство attributes
используется для установки атрибутов входного элемента. Селектор CSS input
выбирает поле ввода. Объект, для которого установлено значение input
, содержит пары "ключ-значение", состоящие из имен атрибутов и значений входного элемента.
Свойство utils.data
содержит данные, на которые можно ссылаться в разметке. Свойство utils.data.dynamic
содержит данные, которые могут измениться во время выполнения программы приложения. Данные могут быть привязаны к DOM, чтобы изменения, внесенные в DOM, отражались в данных компонента и наоборот. Итак, значение ::@data.value
относится к utils.data.dynamic.value.data
. Два двоеточия указывают на то, что между обновлениями DOM и данными компонента будет двойная привязка. В массиве utils.data.dynamic.value.updaters
указаны функции, которые будут отвечать на обновления. Свойство utils.data.dynamic.valid
следует тому же шаблону, но без привязки к DOM.
Свойство utils.texts
определяет текстовый ресурс, на который в markup
ссылается атрибут odom-text
.
Все динамические данные, указанные в data
, попадают в inputGroup.dynamicData
. Чтобы обновить значение, подобное data.dynamic.valid.data
, вы устанавливаете значение непосредственно на inputGroup.dynamicData
. Например, setValidity
устанавливает значение напрямую, используя присвоение inputGroup.dynamicData.valid = valid
. При этом вызывается updateValidity
. Функция updateValidity
получает новое значение в качестве параметра и возвращает значение Boolean
после обновления сообщения. Обратите внимание, что метод updateValue
устанавливает inputGroup.dynamicData.valid
в свой параметр value
, который является строкой. Функция updateValidity
перехватывает значение, проверяет, допустимо ли оно, и возвращает логическое значение. Если значение не является строкой, предполагается, что это Boolean
, поэтому оно возвращается без изменений. Возвращаемое значение - это то, что будет установлено в inputGroup.dynamicData.valid
.
ConfirmationMessage
Подтверждение успешной регистрации будет сделано с помощью ConfirmationMessage. Поместите следующий код в модуль по адресу /odom-signup/src/components/confirmation-message.js
:
Замените комментарий в значении styles
следующим кодом:
Медиа-запрос устанавливает границу компонента в окнах шириной не менее 576px
. Функция ConfirmationMessage
является конструктором. Он возвращает обещание, которое разрешается узлу DOM.
Рендеринг
В этом разделе мы собираемся отобразить компонент Приложение в DOM. Поместите следующий код в модуль по адресу /odom-signup/src/index.js
.
В модуль импортируется Приложение. В IIFE создается экземпляр (app
) компонента. Метод app.render
отображает компонент в DOM. Параметр метода - это селектор CSS для элемента, который должен быть заменен приложением в модели DOM.
В файле по адресу /odom-signup/index.html
поместите следующий код:
Элемент link
в элементе head
добавляет стили на страницу. В файле по адресу /odom-signup/assets/index.css
поместите следующий код CSS:
Стили используются для сброса некоторых стилей по умолчанию. Значение box-sizing
сбрасывается до border-box
для всех элементов. margin
и padding
элемента body
сбрасываются на 0
.
Элемент div#app
- это то, что будет заменено компонентом App. Первый элемент script
включает Одом на страницу через CDN. Второй элемент script
добавляет на страницу основной файл JavaScript, который мы создали ранее.
Сохраните файл. Убедитесь, что все созданные файлы сохранены. Откройте HTML-файл (/odom-signup/index.html
) в браузере. Вы должны увидеть страницу с формой на ней. Если что-то кажется неправильным, вы можете проверить, правильно ли вы выполнили какой-либо шаг, или вы можете использовать файлы в репо.
Введите допустимые значения во все поля и отправьте форму. Вы должны увидеть подтверждающее сообщение. Обновите страницу, введите недопустимое значение в любые поля и отправьте форму. Вы должны увидеть сообщение об ошибке сразу под заголовком формы. Обновите страницу и отправьте форму, не вводя никаких значений в поля. Вы должны увидеть сообщение об ошибке, как и раньше.
Оптимизация
Стили
Если вы проверите элементы страницы с помощью средств разработки в своем браузере, вы должны увидеть 8 элементов style
в элементе head
. Элементы style
предназначены для компонентов Приложение, Регистрация, Форма, Оповещение и InputGroup strong. > (4). Все 4 экземпляра InputGroup используют одинаковые стили. Это делает 3 из style
элементов избыточными. Мы можем избавиться от избыточности, сообщив Одому, что 4 экземпляра InputGroup происходят из одного и того же компонента. Мы можем сделать это, установив идентификатор на InputGroup. В модуле для InputGroup (/odom-signup/src/components/input-group.js
) установите для свойства options.id
значение odom-"input-group"
или любое String
значение, которое вам нравится. В приведенном ниже коде показано, как это сделать.
Сохраните файл, обновите страницу и снова проверьте элементы. На этот раз вы должны увидеть только 5 style
элементов. Одому удалось предотвратить избыточность, не обрабатывая и не добавляя стили для всех экземпляров после первого. Все экземпляры использовали одинаковые стили.
Вложенность узлов DOM
В Odom очень важно избегать вложенности узлов DOM, когда это возможно. Все дочерние компоненты данного компонента создаются сразу. Это означает, что время, необходимое для создания всех дочерних компонентов, примерно равно количеству времени, необходимому для создания компонента, сборка которого занимает больше всего времени.
Предположим, что для создания AlertMessage требуется 100 миллисекунд, а для создания InputGroup - 200 миллисекунд. На создание всех дочерних компонентов Form потребуется примерно 200 миллисекунд. Если бы мы решили поместить все элементы InputGroup в один элемент, например элемент section
, сначала были бы созданы экземпляры InputGroup. После этого будет создан экземпляр AlertMessage. Это означает, что время, необходимое для сборки всех компонентов, будет примерно равно 300 миллисекундам (100 + 200). Мы уже провели такую оптимизацию, сделав все компоненты прямыми потомками корневого элемента Form.
Вывод
Будь то добавление OAuth, разделение процесса регистрации на несколько этапов или что-то еще, я хотел бы посмотреть, как вы можете настроить приложение. Если у вас есть время для этого, поделитесь своим проектом и опытом в разделе комментариев. Спасибо за чтение.