1. Wprowadzenie
Material Komponenty (MDC) pomagają deweloperom wdrażać interfejs Material Design. MDC, stworzona przez zespół inżynierów i projektantów UX w Google, zawiera dziesiątki pięknych i funkcjonalnych komponentów interfejsu. Jest dostępny na Androida, iOS, internet oraz Flutter.material.io/develop |
Usługa MDC Web została zaprojektowana tak, aby można było zintegrować ją z każdą platformą frontendową przy jednoczesnym zachowaniu zasad Material Design. Dzięki poniższym ćwiczeniom w Codelabs dowiesz się, jak utworzyć komponent React, którego podstawą jest MDC Web. Zasady omówione w ramach tego ćwiczenia z programowania można zastosować w dowolnej platformie JavaScript.
Jak zbudowana jest usługa MDC Web
Warstwa JavaScript w MDC Web składa się z 3 klas na komponent: Komponent, Podstawy i Adapter. Ten wzorzec zapewnia MDC Web elastyczność w zakresie integracji z platformami frontendu.
Foundation zawiera logikę biznesową implementującą Material Design. Fundacja nie odwołuje się do żadnych elementów HTML. Pozwala to nam przedstawić abstrakcyjną logikę interakcji HTML do Adaptera. Podstawy ma adapter.
Adapter to interfejs. Foundation odwołuje się do interfejsu adaptera w celu implementacji logiki biznesowej Material Design. Adapter możesz zastosować w różnych platformach, np. Angular lub React. Implementacja adaptera współdziała ze strukturą DOM.
Komponent ma podstawę, a jego zadaniem jest
- Zaimplementuj Adapter, używając kodu JavaScript nieopartego na ramce.
- Podaj metody publiczne pośredniczące w metodach podanych w Podstawach.
Co zapewnia MDC Web
Każdy pakiet w MDC Web ma komponent, podstawę i adapter. Aby utworzyć wystąpienie komponentu, należy przekazać element główny do metody konstruktora komponentu. Komponent implementuje Adapter, który współdziała z elementami DOM i HTML. Następnie Komponent tworzy instancję Foundation, która wywołuje metody Adapter.
Aby zintegrować MDC Web ze platformą, musisz utworzyć własny komponent w wybranym języku/składni. Platforma Komponent implementuje Adapter MDC Web i używa protokołu Foundation sieci MDC.
Co utworzysz
Te ćwiczenia w Codelabs pokazują, jak stworzyć niestandardowy Adapter, który będzie wykorzystywał logikę Foundation do uzyskania komponentu Material Design React. Omawiamy w nim zaawansowane tematy dostępne na stronie Integracja z platformami (w języku angielskim). React jest używane w tym ćwiczeniu jako przykładowa platforma, ale tej metody możesz użyć w przypadku każdej innej platformy.
W ramach tego ćwiczenia w programie utworzysz pasek aplikacji u góry strony i odtworzysz stronę demonstracyjną górnego paska aplikacji. Układ strony demonstracyjnej jest już skonfigurowany, możesz więc zacząć pracę na górnym pasku aplikacji. Górny pasek aplikacji zawiera:
- Ikona nawigacji
- Działania
- Dostępne są 4 wersje: krótki, zawsze zwinięty, stały i widoczny.
Co będzie Ci potrzebne:
- najnowszą wersję Node.js (w pakiecie z npm, menedżerem pakietów JavaScript),
- Przykładowy kod (do pobrania w następnym kroku)
- Podstawowa znajomość języka HTML, CSS, JavaScript i React
Jak oceniasz swój poziom doświadczenia w tworzeniu stron internetowych?
2. Skonfiguruj środowisko programistyczne
Pobierz aplikację startową z programowania
Aplikacja startowa znajduje się w katalogu material-components-web-codelabs-master/mdc-112/starter
.
...lub skopiuj je z GitHuba
Aby skopiować to ćwiczenia z programowania z GitHuba, uruchom te polecenia:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
Instalowanie zależności projektu
Z katalogu startowego material-components-web-codelabs/mdc-112/starter
uruchom polecenie:
npm install
Zobaczysz dużo aktywności, a na końcu terminala powinna pojawić się wiadomość o pomyślnej instalacji:
Uruchamianie aplikacji startowej
W tym samym katalogu uruchom polecenie:
npm start
Rozpocznie się webpack-dev-server
. Aby wyświetlić tę stronę, wpisz w przeglądarce adres http://localhost:8080/.
Gotowe! W przeglądarce powinien być uruchomiony kod startowy strony demonstracyjnej Top App Bar React. Powinna wyświetlić się ściana z tekstem lorem ipsum, pole Sterowanie (w prawym dolnym rogu) i niedokończony górny pasek aplikacji:
Rzuć okiem na kod i projekt
Jeśli otworzysz edytor kodu, katalog projektu powinien wyglądać mniej więcej tak:
Otwórz plik App.js
i sprawdź metodę render
, która zawiera komponent <TopAppBar>
:
App.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>
);
}
Jest to punkt wejścia elementu TopAppBar
w aplikacji.
Otwórz plik TopAppBar.js
, który jest samą klasą React Component
z metodą render
:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. Skład komponentu
W reacie metoda render
zwraca kod HTML komponentu. Komponent górny paska aplikacji wyrenderuje tag <header />
i składa się z 2 głównych sekcji:
- Ikona nawigacji i sekcja tytułu
- Sekcja z ikonami czynności
Jeśli masz pytania dotyczące elementów, które składają się na pasek aplikacji, zapoznaj się z dokumentacją na GitHub.
Zmodyfikuj metodę render()
w TopAppBar.js
, aby wyglądała tak:
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>
);
}
W tym kodzie HTML znajdują się 2 elementy sekcji. Pierwszy z nich zawiera ikonę nawigacji i tytuł. Drugi zawiera ikony działań.
Następnie dodaj metodę 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>
);
}
Programista zaimportuje plik TopAppBar
do aplikacji React i przekaże ikony działań do elementu TopAppBar
. Przykładowy kod inicjujący TopAppBar
jest dostępny w języku App.js
.
Brak metody getMergedStyles
, która jest używana w metodzie render
. Dodaj do klasy TopAppBar
tę metodę JavaScript:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
W metodzie render
brakuje również pola this.classes
, ale omówimy to w dalszej sekcji. Oprócz brakującej metody pobierania (this.classes
) są jeszcze fragmenty kodu TopAppBar
, które musisz wdrożyć, aby górny pasek aplikacji mógł się prawidłowo renderować.
Elementy komponentu React, których nadal brakuje na górnym pasku aplikacji:
- Zainicjowana podstawa
- Metody przenoszenia do podstawy
- Znacznik JSX
- Zarządzanie wariantami (stałe, krótkie, zawsze zwinięty, widoczne)
Realizacja
- Zaimplementuj metody Adapter.
- Zainicjuj Foundation w tabeli
componentDidMount
. - Wywołaj metodę Foundation.destroy w tabeli
componentWillUnmount
. - Skonfiguruj zarządzanie wariantami za pomocą metody pobierania, która łączy odpowiednie nazwy klas.
4. Wdrażanie metod związanych z adapterami
Komponent JS TopAppBar
niebędący ramką implementuje te metody Adapter (wymienione szczegółowo tutaj):
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
Ponieważ React zawiera zdarzenia syntetyczne oraz różne sprawdzone metody i wzorce dotyczące kodowania, trzeba ponownie wdrożyć metody narzędzia Adapter.
Metoda pobierania adaptera
W pliku TopAppBar.js
dodaj do elementu TopAppBar
tę metodę JavaScriptu:
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,
};
}
Interfejsy API adaptera do rejestracji zdarzeń przewijania i zmiany rozmiaru są zaimplementowane tak samo jak pozostałe wersje JavaScriptu, ponieważ React nie ma żadnego zdarzenia syntetycznego do przewijania lub zmiany rozmiaru i odracza do natywnego systemu zdarzeń DOM. Funkcja getViewPortScrollY
musi też uwzględnić natywny DOM, ponieważ jest to funkcja w obiekcie window
, którego nie ma w interfejsie API React. Implementacje adapterów będą się różnić w zależności od platformy.
Możesz zauważyć, że brakuje pola this.setStyle
, które jest wywoływane przez metodę get adapter
. W pliku TopAppBar.js
dodaj brakującą metodę JavaScript do klasy TopAppBar
:
setStyle = (varName, value) => {
const updatedStyle = Object.assign({}, this.state.style);
updatedStyle[varName] = value;
this.setState({style: updatedStyle});
}
Adapter jest już wdrożony. Pamiętaj, że w tym momencie w konsoli mogą pojawić się błędy, ponieważ pełna implementacja nie została jeszcze ukończona. W następnej sekcji dowiesz się, jak dodawać i usuwać klasy CSS.
5. Wdrażanie metod komponentów
Zarządzanie wariantami i klasami
React nie ma interfejsu API do zarządzania klasami. Aby naśladować metody dodawania i usuwania klas CSS w natywnym JavaScripcie, dodaj zmienną stanu classList
. W TopAppBar
są 3 fragmenty kodu, które współdziałają z klasami CSS:
<TopAppBar />
za pomocą właściwościclassName
.- Metoda Adapter za pomocą
addClass
lubremoveClass
. - Zakodowany na stałe w komponencie React
<TopAppBar />
.
Najpierw dodaj następujący import na początku listy TopAppBar.js
, pod istniejącymi importami:
import classnames from 'classnames';
Następnie dodaj ten kod do deklaracji klasy w komponencie 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,
});
}
...
}
Jeśli otworzysz stronę http://localhost:8080, pola wyboru ustawień powinny teraz włączać i wyłączać nazwy klas w DOM.
Dzięki temu kodowi TopAppBar
może używać wielu deweloperów. Deweloperzy mogą korzystać z interfejsu API TopAppBar
, nie martwiąc się o szczegóły implementacji klas CSS.
Udało Ci się wdrożyć adapter. W następnej sekcji dowiesz się, jak utworzyć instancję Fundacja.
Montaż i odłączanie elementu
Wystąpienie podstawowe odbywa się w metodzie componentDidMount
.
Najpierw zaimportuj podstawowe informacje o pasku aplikacji MDC, dodając następujący import po dotychczasowych importach w TopAppBar.js
:
import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';
Następnie dodaj do klasy TopAppBar
ten kod JavaScript:
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();
}
...
}
Jedną z dobrych metod kodowania w React jest zdefiniowanie obiektów propType i defaultProps. Po zakończeniu importowania do TopAppBar.js dodaj ten import:
import PropTypes from 'prop-types';
Następnie dodaj ten kod na końcu TopAppBar.js
(po klasie komponentu):
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,
};
Udało Ci się zaimplementować górny komponent React na pasku aplikacji. Jeśli przejdziesz na stronę http://localhost:8080, możesz wypróbować stronę demonstracyjną. Strona demonstracyjna będzie działać tak samo jak strona demonstracyjna MEDC Web. Strona demonstracyjna powinna wyglądać tak:
6. Podsumowanie
W tym samouczku pokazaliśmy, jak pakować zawartość biblioteki MDC Web Foundation do użytku w aplikacji React. W GitHub i npm znajduje się kilka bibliotek, które opakowują komponenty MDC Web Komponenty zgodnie z opisem w sekcji Integracja z platformami. Zalecamy skorzystanie z listy dostępnej tutaj. Ta lista zawiera też inne platformy, np. Angular czy Vue.
Ten samouczek przedstawia naszą decyzję o podzieleniu kodu MDC Web na 3 części: Podstawy, Adapter i Komponent. Taka architektura umożliwia komponentom współdzielenie wspólnego kodu przy pracy ze wszystkimi platformami. Dziękujemy za wypróbowanie Material Komponents React i zapoznaj się z naszą nową biblioteką MDC React. Mamy nadzieję, że to ćwiczenie z programowania Ci się podobało.