1. Einführung
Mit Material Components (MDC) können Entwickler Material Design implementieren. MDC wurde von einem Team von Entwicklern und UX-Designern bei Google entwickelt und bietet Dutzende ansprechender und funktionaler UI-Komponenten. Es ist für Android, iOS, Web und Flutter verfügbar.material.io/develop |
MDC Web wurde für die Integration in jedes Frontend-Framework entwickelt, wobei die Prinzipien des Material Design aufrechterhalten werden. Im folgenden Codelab erfahren Sie, wie Sie eine React-Komponente erstellen, die auf MDC Web basiert. Die in diesem Codelab vermittelten Prinzipien können auf jedes JavaScript-Framework angewendet werden.
So funktioniert MDC Web
Die JavaScript-Ebene von MDC Web besteht aus drei Klassen pro Komponente: Component, Foundation und Adapter. Durch dieses Muster kann MDC Web flexibel in Frontend-Frameworks integrieren.
Die Foundation enthält die Geschäftslogik, die Material Design implementiert. Die Foundation verweist nicht auf HTML-Elemente. So können wir die HTML-Interaktionslogik in den Adapter abstrahieren. Foundation hat einen Adapter.
Der Adapter ist eine Schnittstelle. Die Adapter-Schnittstelle wird von der Foundation zur Implementierung der Material Design-Geschäftslogik verwendet. Sie können den Adapter in verschiedenen Frameworks wie Angular oder React implementieren. Eine Adapterimplementierung interagiert mit der DOM-Struktur.
Die Komponente hat eine Grundlage und ihre Aufgabe besteht darin,
- Implementieren Sie den Adapter mithilfe von Nicht-Framework-JavaScript und
- Stellen Sie öffentliche Methoden bereit, die auf Methoden in der Foundation verweisen.
Was MDC Web bietet
Jedes Paket in MDC Web enthält eine Komponente, eine Grundlage und einen Adapter. Wenn Sie eine Komponente instanziieren möchten, müssen Sie der Konstruktormethode der Komponente das Stammelement übergeben. Die Komponente implementiert einen Adapter, der mit den DOM- und HTML-Elementen interagiert. Die Component instanziiert dann die Foundation, wodurch die Adapter-Methoden aufgerufen werden.
Wenn Sie MDC Web in ein Framework einbinden möchten, müssen Sie Ihre eigene Komponente in der Sprache/Syntax dieses Frameworks erstellen. Die Komponente des Frameworks implementiert den Adapter von MDC Web und verwendet die Foundation von MDC Web.
Umfang
In diesem Codelab wird gezeigt, wie Sie einen benutzerdefinierten Adapter erstellen, um die Foundation-Logik für eine Material Design-React-Komponente zu verwenden. Er behandelt die weiterführenden Themen unter In Frameworks integrieren. In diesem Codelab wird React als Beispiel-Framework verwendet, aber dieser Ansatz kann auf jedes andere Framework angewendet werden.
In diesem Codelab erstellen Sie die obere App-Leiste und die Demoseite für die obere App-Leiste neu. Das Layout der Demoseite ist bereits eingerichtet, sodass Sie mit der Arbeit an der oberen App-Leiste beginnen können. Die obere App-Leiste enthält Folgendes:
- Navigationssymbol
- Maßnahmen
- Es gibt vier Varianten: kurze, immer minimiert, feste und gut sichtbare Varianten.
Sie benötigen:
- Eine aktuelle Version von Node.js (im Lieferumfang von npm, einem JavaScript-Paketmanager)
- Beispielcode (wird im nächsten Schritt heruntergeladen)
- Grundkenntnisse in HTML, CSS, JavaScript und React
Wie würden Sie Ihre Erfahrung mit der Webentwicklung bewerten?
2. Entwicklungsumgebung einrichten
Codelab-App für den Einstieg herunterladen
Die Starter-App befindet sich im Verzeichnis material-components-web-codelabs-master/mdc-112/starter
.
…oder es aus GitHub klonen
Führen Sie die folgenden Befehle aus, um dieses Codelab von GitHub zu klonen:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
Projektabhängigkeiten installieren
Führen Sie im Startverzeichnis material-components-web-codelabs/mdc-112/starter
Folgendes aus:
npm install
Sie sehen viele Aktivitäten und am Ende sollte im Terminal eine erfolgreiche Installation angezeigt werden:
Start-App ausführen
Führen Sie im selben Verzeichnis Folgendes aus:
npm start
webpack-dev-server
wird gestartet. Rufen Sie die Seite mit Ihrem Browser unter http://localhost:8080/ auf.
Fertig! Der Startercode für die React-Demoseite der oberen App-Leiste sollte in Ihrem Browser ausgeführt werden. Sie sollten eine Wand mit lorem ipsum-Text, ein Feld Steuerelemente (unten rechts) und eine unfertige obere App-Leiste sehen:
Code und Projekt ansehen
Wenn Sie Ihren Code-Editor öffnen, sollte das Projektverzeichnis in etwa so aussehen:
Öffnen Sie die Datei App.js
und sehen Sie sich die Methode render
an, die die Komponente <TopAppBar>
enthält:
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>
);
}
Dies ist der Einstiegspunkt für die TopAppBar
in der Anwendung.
Öffnen Sie die Datei TopAppBar.js
. Dies ist eine einfache React-Component
-Klasse mit einer render
-Methode:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. Zusammensetzung der Komponente
In React gibt die Methode render
den HTML-Code der Komponente aus. Die Komponente der oberen App-Leiste rendert ein <header />
-Tag und besteht aus zwei Hauptabschnitten:
- Navigationssymbol und Titelbereich
- Bereich für Aktionssymbole
Weitere Informationen zu den Elementen der oberen App-Leiste finden Sie in der Dokumentation auf GitHub.
Ändern Sie die Methode render()
in TopAppBar.js
so:
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>
);
}
Dieses HTML-Dokument enthält zwei Abschnittselemente. Die erste enthält ein Navigationssymbol und einen Titel. Die zweite enthält Aktionssymbole.
Fügen Sie als Nächstes die Methode renderActionItems
hinzu:
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>
);
}
Ein Entwickler importiert TopAppBar
in seine React-Anwendung und übergibt Aktionssymbole an das TopAppBar
-Element. Im Beispielcode wird eine TopAppBar
in App.js
initialisiert.
Die Methode getMergedStyles
fehlt, die in der Methode render
verwendet wird. Fügen Sie der Klasse TopAppBar
die folgende JavaScript-Methode hinzu:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
this.classes
fehlt auch in der Methode render
, wird aber in einem späteren Abschnitt behandelt. Neben der fehlenden Getter-Methode this.classes
müssen Sie noch Teile der TopAppBar
implementieren, damit die obere App-Leiste richtig gerendert werden kann.
In der oberen App-Leiste fehlen noch folgende Teile der React-Komponente:
- Eine initialisierte Grundlage
- Adaptermethoden, die an die Foundation übergeben werden
- JSX-Markup
- Variantenverwaltung (fixiert, kurz, immer minimiert, gut sichtbar)
Der Ansatz
- Implementieren Sie die Adapter-Methoden.
- Initialisieren Sie die Grundlage in der
componentDidMount
. - Rufen Sie die Methode Foundation.destroy in der
componentWillUnmount
auf. - Legen Sie die Variantenverwaltung über eine Getter-Methode fest, die die entsprechenden Klassennamen kombiniert.
4. Adaptermethoden implementieren
Die nicht-Framework-JS-Komponente TopAppBar
implementiert die folgenden Adapter-Methoden, die hier ausführlich aufgeführt sind:
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
Da React synthetische Ereignisse und andere Best Practices für die Programmierung sowie -muster hat, müssen die Adapter-Methoden neu implementiert werden.
Adapter-Getter-Methode
Fügen Sie in der Datei TopAppBar.js
der Variablen TopAppBar
die folgende JavaScript-Methode hinzu:
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,
};
}
Die Adapter-APIs für die Registrierung von Scroll- und Größenänderungsereignissen werden identisch mit der JS-Version ohne Framework implementiert, da React keine synthetischen Ereignisse zum Scrollen oder Ändern der Größe hat und stattdessen das native DOM-Ereignissystem verwendet. getViewPortScrollY
muss auch an das native DOM übergeben werden, da es sich um eine Funktion des window
-Objekts handelt, das nicht in der React-API enthalten ist. Die Adapterimplementierungen unterscheiden sich je nach Framework.
Möglicherweise ist this.setStyle
nicht vorhanden, das von der Methode get adapter
aufgerufen wird. Fügen Sie in der Datei TopAppBar.js
der Klasse TopAppBar
die fehlende JavaScript-Methode hinzu:
setStyle = (varName, value) => {
const updatedStyle = Object.assign({}, this.state.style);
updatedStyle[varName] = value;
this.setState({style: updatedStyle});
}
Sie haben gerade den Adapter implementiert. Möglicherweise werden in der Konsole Fehler angezeigt, da die vollständige Implementierung noch nicht abgeschlossen ist. Im nächsten Abschnitt erfahren Sie, wie Sie CSS-Klassen hinzufügen und entfernen.
5. Komponentenmethoden implementieren
Varianten und Klassen verwalten
React hat keine API zum Verwalten von Klassen. Fügen Sie die Statusvariable classList
hinzu, um die CSS-Klassenmethoden des nativen JavaScript-Codes zu imitieren. In TopAppBar
gibt es drei Code-Abschnitte, die mit CSS-Klassen interagieren:
<TopAppBar />
-Komponente über das AttributclassName
.- Die Methode Adapter über
addClass
oderremoveClass
- In der
<TopAppBar />
-React-Komponente hartcodiert.
Fügen Sie zuerst den folgenden Import oben in TopAppBar.js
unter den vorhandenen Importen hinzu:
import classnames from 'classnames';
Fügen Sie dann den folgenden Code in die Klassendeklaration der TopAppBar
-Komponente ein:
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,
});
}
...
}
Wenn Sie http://localhost:8080 aufrufen, können Sie mit den Steuerelementen die Klassennamen im DOM aktivieren bzw. deaktivieren.
Dieser Code macht TopAppBar
für viele Entwickler nutzbar. Entwickler können mit der TopAppBar
API interagieren, ohne sich um die Implementierungsdetails von CSS-Klassen kümmern zu müssen.
Sie haben den Adapter jetzt erfolgreich implementiert. Im nächsten Abschnitt erfahren Sie, wie Sie eine Foundation instanziieren.
Komponente bereitstellen und trennen
Die Instanziierung Foundation erfolgt in der Methode componentDidMount
.
Importieren Sie zuerst die Grundlagen der MDC Top App Bar. Fügen Sie dazu den folgenden Import nach den vorhandenen Importen in TopAppBar.js
hinzu:
import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';
Fügen Sie als Nächstes den folgenden JavaScript-Code in die Klasse TopAppBar
ein:
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();
}
...
}
Eine gute React-Programmierpraxis besteht darin, propTypes und defaultProps zu definieren. Fügen Sie den folgenden Import nach den vorhandenen Importen in TopAppBar.js hinzu:
import PropTypes from 'prop-types';
Fügen Sie dann den folgenden Code unter TopAppBar.js
(nach der Component-Klasse) ein:
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,
};
Sie haben die Top App Bar React-Komponente erfolgreich implementiert. Wenn Sie http://localhost:8080 aufrufen, können Sie die Demoseite ausprobieren. Die Demoseite funktioniert genauso wie die Demoseite von MDC Web. Die Demoseite sollte so aussehen:
6. Zusammenfassung
In dieser Anleitung haben wir gezeigt, wie Sie die Foundation von MDC Web für die Verwendung in einer React-Anwendung einbinden. Es gibt einige Bibliotheken auf GitHub und npm, die MDC-Webkomponenten umschließen, wie unter In Frameworks integrieren beschrieben. Wir empfehlen, diese Liste zu verwenden. Diese Liste enthält neben React auch andere Frameworks wie Angular und Vue.
In dieser Anleitung wird unsere Entscheidung erläutert, den MDC-Webcode in drei Teile zu unterteilen: Grundlage, Adapter und Komponente. Diese Architektur ermöglicht es Komponenten, gemeinsamen Code zu nutzen, während sie mit allen Frameworks arbeiten. Vielen Dank, dass Sie Material Components React ausprobiert haben. Sehen Sie sich auch unsere neue Bibliothek MDC React an. Wir hoffen, dass Ihnen dieses Codelab gefallen hat.