О практической работе
1. Введение
Material Components (MDC) помогают разработчикам реализовать Material Design. Созданный командой инженеров и UX-дизайнеров Google, MDC включает в себя десятки красивых и функциональных компонентов пользовательского интерфейса и доступен для Android, iOS, Интернета и Flutter.material.io/develop. |
MDC Web спроектирован для интеграции в любую интерфейсную среду, сохраняя при этом принципы Material Design. Следующая лаборатория кода поможет вам создать компонент React, который использует MDC Web в качестве основы. Принципы, изученные в этой лаборатории кода, можно применить к любой среде JavaScript.
Как устроен MDC Web
Уровень JavaScript MDC Web состоит из трех классов для каждого компонента: Component , Foundation и Adaptor . Этот шаблон дает MDC Web гибкость для интеграции с интерфейсными платформами.
Foundation содержит бизнес-логику, реализующую Material Design. Фонд не ссылается ни на какие элементы HTML. Это позволяет нам абстрагировать логику взаимодействия HTML в адаптер . У Foundation есть адаптер .
Адаптер — это интерфейс. Интерфейс адаптера используется Фондом для реализации бизнес-логики Material Design. Вы можете реализовать адаптер в различных средах, таких как Angular или React. Реализация адаптера взаимодействует со структурой DOM.
Компонент имеет основу , и его роль заключается в
- Реализуйте адаптер , используя нефреймворковый JavaScript, и
- Предоставьте общедоступные методы, которые проксируют методы Foundation .
Что предоставляет MDC Web
Каждый пакет в MDC Web поставляется с компонентом , основой и адаптером . Чтобы создать экземпляр компонента, вы должны передать корневой элемент методу конструктора компонента. Компонент реализует адаптер , который взаимодействует с элементами DOM и HTML. Затем Компонент создает экземпляр Foundation , который вызывает методы Адаптера .
Чтобы интегрировать MDC Web в платформу, вам необходимо создать собственный компонент на языке/синтаксисе этой платформы. Компонент платформы реализует адаптер MDC Web и использует MDC Web Foundation .
Что ты построишь
В этой лаборатории кода показано, как создать собственный адаптер для использования логики Foundation для создания компонента Material Design React. В нем рассматриваются сложные темы, представленные в разделе «Интеграция в платформы» . React используется в этой лаборатории кода в качестве примера платформы, но этот подход можно применить к любой другой платформе.
В этой лаборатории кода вы создадите верхнюю панель приложений и воссоздадите демонстрационную страницу верхней панели приложений. Макет демонстрационной страницы уже настроен, поэтому вы можете начать работу с верхней панелью приложений. Верхняя панель приложений будет включать в себя:
- Значок навигации
- Действия
- Доступно 4 варианта: короткий , всегда свернутый , фиксированный и заметный .
Что вам понадобится:
- Последняя версия Node.js (которая поставляется в комплекте с npm , менеджером пакетов JavaScript).
- Пример кода (можно загрузить на следующем шаге)
- Базовые знания HTML, CSS, JavaScript и React.
Как бы вы оценили свой уровень опыта веб-разработки?
2. Настройка среды разработки
Загрузите начальное приложение Codelab.
Стартовое приложение находится в каталоге material-components-web-codelabs-master/mdc-112/starter
.
...или клонируйте его с GitHub
Чтобы клонировать эту кодовую лабораторию из GitHub, выполните следующие команды:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
Установить зависимости проекта
Из стартового каталогаmaterial material-components-web-codelabs/mdc-112/starter
запустите:
npm install
Вы увидите много активности, и в конце ваш терминал должен показать успешную установку:
Запустите стартовое приложение
В том же каталоге запустите:
npm start
webpack-dev-server
запустится. Направьте свой браузер на http://localhost:8080/, чтобы увидеть страницу.
Успех! Стартовый код для демонстрационной страницы Top App Bar React должен быть запущен в вашем браузере. Вы должны увидеть стену текста lorem ipsum , поле управления (внизу справа) и незаконченную верхнюю панель приложений:
Взгляните на код и проект
Если вы откроете редактор кода, каталог проекта должен выглядеть примерно так:
Откройте файл App.js
и посмотрите на метод render
, который включает компонент <TopAppBar>
:
Приложение.js
render() {
const {isFixed, isShort, isRtl, isProminent, isAlwaysCollapsed, shouldReinit} = this.state;
return (
<section
dir={isRtl ? 'rtl' : 'ltr'}
className='mdc-typography'>
{
shouldReinit ? null :
<TopAppBar
navIcon={this.renderNavIcon()}
short={isShort}
prominent={isProminent}
fixed={isFixed}
alwaysCollapsed={isAlwaysCollapsed}
title='Mountain View, CA'
actionItems={this.actionItems}
/>
}
<div className={classnames('mdc-top-app-bar--fixed-adjust', {
'mdc-top-app-bar--short-fixed-adjust': isShort || isAlwaysCollapsed,
'mdc-top-app-bar--prominent-fixed-adjust': isProminent,
})}>
{this.renderDemoParagraphs()}
</div>
{this.renderControls()}
</section>
);
}
Это точка входа для TopAppBar
в приложении.
Откройте файл TopAppBar.js
, который представляет собой простой класс Component
React с методом render
:
ТопAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. Состав компонента
В React метод render
выводит HTML-код компонента. Компонент Top App Bar отображает тег <header />
и состоит из двух основных разделов:
- Значок навигации и заголовок раздела
- Раздел значков действий
Если у вас есть вопросы об элементах, составляющих верхнюю панель приложений, посетите документацию на GitHub .
Измените метод render()
в TopAppBar.js
, чтобы он выглядел следующим образом:
render() {
const {
title,
navIcon,
} = this.props;
return (
<header
className={this.classes}
style={this.getMergedStyles()}
ref={this.topAppBarElement}
>
<div className='mdc-top-app-bar__row'>
<section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-start'>
{navIcon ? navIcon : null}
<span className="mdc-top-app-bar__title">
{title}
</span>
</section>
{this.renderActionItems()}
</div>
</header>
);
}
В этом HTML есть два элемента раздела. Первый содержит значок навигации и заголовок. Второй содержит значки действий.
Затем добавьте метод renderActionItems
:
renderActionItems() {
const {actionItems} = this.props;
if (!actionItems) {
return;
}
return (
<section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-end' role='toolbar'>
{/* need to clone element to set key */}
{actionItems.map((item, key) => React.cloneElement(item, {key}))}
</section>
);
}
Разработчик импортирует TopAppBar
в свое приложение React и передаст значки действий в элемент TopAppBar
. Вы можете увидеть пример кода, инициализирующего TopAppBar
в App.js
Отсутствует метод getMergedStyles
, который используется в методе render
. Добавьте следующий метод JavaScript в класс TopAppBar
:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
this.classes
также отсутствует в методе render
, но будет рассмотрен в следующем разделе. Помимо отсутствующего метода получения this.classes
, есть еще части TopAppBar
, которые необходимо реализовать, прежде чем верхняя панель приложений сможет правильно отображаться.
Части компонента React, которые все еще отсутствуют в верхней панели приложений:
- Инициализированный фундамент
- Методы адаптера для перехода в фундамент
- JSX-разметка
- Вариант управления (фиксированный, короткий, всегда свернутый, заметный)
Подход
- Реализуйте методы адаптера .
- Инициализируйте Foundation в
componentDidMount
. - Вызовите метод Foundation.destroy в
componentWillUnmount
. - Установите управление вариантами с помощью метода получения, который объединяет соответствующие имена классов.
4. Реализация методов адаптера
Нефреймворковый JS TopAppBar
Component реализует следующие методы адаптера (подробно перечислены здесь ):
-
hasClass()
-
addClass()
-
removeClass()
-
registerNavigationIconInteractionHandler()
-
deregisterNavigationIconInteractionHandler()
-
notifyNavigationIconClicked()
-
setStyle()
-
getTopAppBarHeight()
-
registerScrollHandler()
-
deregisterScrollHandler()
-
registerResizeHandler()
-
deregisterResizeHandler()
-
getViewportScrollY()
-
getTotalActionItems()
Поскольку в React есть синтетические события и различные лучшие практики и шаблоны кодирования, методы адаптера необходимо переопределить.
Метод получения адаптера
В файле TopAppBar.js
добавьте в TopAppBar
следующий метод JavaScript:
get adapter() {
const {actionItems} = this.props;
return {
hasClass: (className) => this.classes.split(' ').includes(className),
addClass: (className) => this.setState({classList: this.state.classList.add(className)}),
removeClass: (className) => {
const {classList} = this.state;
classList.delete(className);
this.setState({classList});
},
setStyle: this.setStyle,
getTopAppBarHeight: () => this.topAppBarElement.current.clientHeight,
registerScrollHandler: (handler) => window.addEventListener('scroll', handler),
deregisterScrollHandler: (handler) => window.removeEventListener('scroll', handler),
registerResizeHandler: (handler) => window.addEventListener('resize', handler),
deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
getViewportScrollY: () => window.pageYOffset,
getTotalActionItems: () => actionItems && actionItems.length,
};
}
API-интерфейсы адаптера для регистрации событий прокрутки и изменения размера реализованы идентично версии JS без платформы, поскольку React не имеет синтетических событий для прокрутки или изменения размера и подчиняется собственной системе событий DOM. getViewPortScrollY
также необходимо использовать собственный DOM, поскольку это функция объекта window
, которой нет в API React. Реализации адаптера будут разными для каждой платформы.
Вы можете заметить, что отсутствует this.setStyle
, который вызывается методом get adapter
. В файле TopAppBar.js
добавьте недостающий метод JavaScript в класс TopAppBar
:
setStyle = (varName, value) => {
const updatedStyle = Object.assign({}, this.state.style);
updatedStyle[varName] = value;
this.setState({style: updatedStyle});
}
Вы только что реализовали адаптер ! Обратите внимание, что на этом этапе вы можете увидеть ошибки в консоли, поскольку полная реализация еще не завершена. В следующем разделе вы узнаете, как добавлять и удалять классы CSS.
5. Реализация методов компонента
Управление вариантами и классами
У React нет API для управления классами. Чтобы имитировать собственные методы добавления/удаления классов CSS в JavaScript, добавьте переменную состояния classList
. В TopAppBar
есть три фрагмента кода, которые взаимодействуют с классами CSS:
- Компонент
<TopAppBar />
через свойствоclassName
. - Метод адаптера через
addClass
илиremoveClass
. - Жестко запрограммировано в компоненте React
<TopAppBar />
.
Сначала добавьте следующий импорт вверху TopAppBar.js
под существующим импортом:
import classnames from 'classnames';
Затем добавьте следующий код в объявление класса компонента TopAppBar
:
export default class TopAppBar extends React.Component {
constructor(props) {
super(props);
this.topAppBarElement = React.createRef();
}
state = {
classList: new Set(),
style: {},
};
get classes() {
const {classList} = this.state;
const {
alwaysCollapsed,
className,
short,
fixed,
prominent,
} = this.props;
return classnames('mdc-top-app-bar', Array.from(classList), className, {
'mdc-top-app-bar--fixed': fixed,
'mdc-top-app-bar--short': short,
'mdc-top-app-bar--short-collapsed': alwaysCollapsed,
'mdc-top-app-bar--prominent': prominent,
});
}
...
}
Если вы перейдете по адресу http://localhost:8080, флажки «Управление» теперь должны включать/выключать имена классов из DOM.
Этот код делает TopAppBar
доступным для использования многими разработчиками. Разработчики могут взаимодействовать с API TopAppBar
, не беспокоясь о деталях реализации классов CSS.
Теперь вы успешно внедрили адаптер. В следующем разделе вы узнаете, как создать экземпляр Foundation .
Монтаж и демонтаж компонента
Создание экземпляра Foundation происходит в методе componentDidMount
.
Сначала импортируйте основы верхней панели приложений MDC, добавив следующий импорт после существующего импорта в TopAppBar.js
:
import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';
Затем добавьте следующий код JavaScript в класс TopAppBar
:
export default class TopAppBar extends React.Component {
...
foundation_ = null;
componentDidMount() {
this.initializeFoundation();
}
componentWillUnmount() {
this.foundation_.destroy();
}
initializeFoundation = () => {
if (this.props.short) {
this.foundation_ = new MDCShortTopAppBarFoundation(this.adapter);
} else if (this.props.fixed) {
this.foundation_ = new MDCFixedTopAppBarFoundation(this.adapter);
} else {
this.foundation_ = new MDCTopAppBarFoundation(this.adapter);
}
this.foundation_.init();
}
...
}
Одна из хороших практик кодирования React — определение propTypes и defaultProps. Добавьте следующий импорт после существующего импорта в TopAppBar.js:
import PropTypes from 'prop-types';
Затем добавьте следующий код в конец TopAppBar.js
(после класса Component):
import PropTypes from 'prop-types';
TopAppBar.propTypes = {
alwaysCollapsed: PropTypes.bool,
short: PropTypes.bool,
fixed: PropTypes.bool,
prominent: PropTypes.bool,
title: PropTypes.string,
actionItems: PropTypes.arrayOf(PropTypes.element),
navIcon: PropTypes.element,
};
TopAppBar.defaultProps = {
alwaysCollapsed: false,
short: false,
fixed: false,
prominent: false,
title: '',
actionItems: null,
navIcon: null,
};
Теперь вы успешно реализовали компонент React Top App Bar. Если вы перейдете по адресу http://localhost:8080, вы сможете поиграть с демонстрационной страницей. Демонстрационная страница будет работать так же, как и демонстрационная страница MDC Web . Демо-страница должна выглядеть так:
6. Заворачивать
В этом уроке мы рассмотрели, как обернуть MDC Web Foundation для использования в приложении React. На Github и npm есть несколько библиотек, которые обертывают веб-компоненты MDC, как описано в разделе «Интеграция в платформы» . Мы рекомендуем вам использовать список, найденный здесь . В этот список также входят другие фреймворки помимо React, такие как Angular и Vue.
В этом руководстве рассказывается о нашем решении разделить веб-код MDC на три части: основу , адаптер и компонент. Эта архитектура позволяет компонентам использовать общий код при работе со всеми платформами. Спасибо, что попробовали Material Components React. Пожалуйста, ознакомьтесь с нашей новой библиотекой MDC React . Мы надеемся, что вам понравилась эта кодовая лаборатория!