1. Introduzione
Material Components (MDC) consente agli sviluppatori di implementare Material Design. Creato da un team di ingegneri e designer UX di Google, MDC offre dozzine di componenti dell'interfaccia utente belli e funzionali ed è disponibile per Android, iOS, web e Flutter.material.io/develop |
MDC Web è progettato per essere integrato in qualsiasi framework frontend, rispettando al contempo i principi di Material Design. Il seguente codelab ti guida nella creazione di un componente React che utilizza MDC Web come base. I principi appresi in questo codelab possono essere applicati a qualsiasi framework JavaScript.
Come viene creato MDC Web
Il livello JavaScript di MDC Web è composto da tre classi per componente: Componente, Base e Adattatore. Questo pattern offre a MDC Web la flessibilità di integrarsi con i framework frontend.
Foundation contiene la logica di business che implementa Material Design. La sezione Elementi di base non fa riferimento ad alcun elemento HTML. In questo modo possiamo astrarre la logica di interazione HTML nell'adattatore. Foundation ha un adattatore.
L'adattatore è un'interfaccia. La Foundation fa riferimento all'interfaccia dell'adattatore per implementare la logica di business di Material Design. Puoi implementare l'adattatore in diversi framework, come Angular o React. Un'implementazione di un Adapter interagisce con la struttura DOM.
Il Componente ha una Fondazione e il suo ruolo è
- Implementa l'adattatore utilizzando JavaScript non framework e
- Fornisci metodi pubblici che fungono da proxy per i metodi in Foundation.
Che cosa offre MDC Web
Ogni pacchetto in MDC Web è dotato di un Componente, una Base e un Adattatore. Per creare un'istanza di un Componente, devi passare l'elemento radice al metodo costruttore del componente. Il Componente implementa un Adattatore, che interagisce con gli elementi DOM e HTML. Il Componente esegue quindi l'inizializzazione di Foundation, che chiama i metodi di Adapter.
Per integrare MDC Web in un framework, devi creare il tuo componente nel linguaggio/nella sintassi del framework. Il Componente del framework implementa l'Adattatore di MDC Web e utilizza la Fondazione di MDC Web.
Cosa creerai
Questo codelab mostra come creare un adattatore personalizzato per utilizzare la logica Foundation per ottenere un componente di reazione Material Design. Tratta gli argomenti avanzati descritti in Integrazione nei framework. In questo codelab, React viene utilizzato come framework di esempio, ma questo approccio può essere applicato a qualsiasi altro framework.
In questo codelab, creerai la barra delle app in alto e ricreerai la pagina di demo della barra delle app in alto. Il layout della pagina di esempio è già configurato, quindi puoi iniziare a lavorare sulla barra delle app in alto. La barra delle app superiore includerà:
- Icona di navigazione
- Attività
- Sono disponibili 4 varianti: corta, sempre compressa, fissa ed in evidenza.
Occorrente:
- Una versione recente di Node.js (incorporata in bundle con npm, un gestore di pacchetti JavaScript)
- Il codice di esempio (da scaricare nel passaggio successivo)
- Conoscenza di base di HTML, CSS, JavaScript e React
Come valuteresti il tuo livello di esperienza nello sviluppo web?
2. Configura ambiente di sviluppo
Scarica l'app codelab iniziale
L'app iniziale si trova nella directory material-components-web-codelabs-master/mdc-112/starter
.
…oppure clonalo da GitHub
Per clonare questo codelab da GitHub, esegui questi comandi:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
Installare le dipendenze del progetto
Dalla directory iniziale material-components-web-codelabs/mdc-112/starter
, esegui:
npm install
Vedrai molte attività e, al termine, il terminale dovrebbe mostrare un'installazione riuscita:
Eseguire l'app iniziale
Nella stessa directory, esegui:
npm start
Inizierà webpack-dev-server
. Apri il browser all'indirizzo http://localhost:8080/ per visualizzare la pagina.
Operazione riuscita. Il codice di avvio per la pagina della demo di React della barra delle app superiore dovrebbe essere in esecuzione nel browser. Dovresti vedere un testo lorem ipsum, una casella Controlli (in basso a destra) e una barra delle app in alto non completata:
Dai un'occhiata al codice e al progetto
Se apri l'editor di codice, la directory del progetto dovrebbe avere il seguente aspetto:
Apri il file App.js
e osserva il metodo render
, che include il componente <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>
);
}
Questo è il punto di ingresso per TopAppBar
nell'applicazione.
Apri il file TopAppBar.js
, che è una classe Component
semplice con un metodo render
:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. Composizione del componente
In React, il metodo render
restituisce l'HTML del componente. Il componente Top AppBar mostrerà un tag <header />
e sarà composto da due sezioni principali:
- Sezione di icone di navigazione e titoli
- Sezione delle icone di azione
Se hai domande sugli elementi che compongono la barra delle app superiore, consulta la documentazione su GitHub.
Modifica il metodo render()
in TopAppBar.js
in modo che abbia il seguente aspetto:
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>
);
}
Questo codice HTML contiene due elementi section. La prima contiene un'icona di navigazione e un titolo. La seconda contiene le icone di azione.
Poi, aggiungi il metodo 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>
);
}
Uno sviluppatore importerà TopAppBar
nella propria applicazione React e passerà le icone di azione all'elemento TopAppBar
. Puoi vedere un codice di esempio che inizializza un TopAppBar
in App.js
.
Manca il metodo getMergedStyles
, utilizzato nel metodo render
. Aggiungi il seguente metodo JavaScript alla classe TopAppBar
:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
Anche this.classes
non è presente nel metodo render
, ma verrà trattato in una sezione successiva. Oltre al metodo getter mancante, this.classes
, è necessario implementare alcune parti della TopAppBar
prima che la barra delle app superiore possa essere visualizzata correttamente.
I componenti del componente React ancora mancanti nella barra delle app in alto sono:
- Una base inizializzata
- Metodi di adattatore da usare per accedere agli elementi di base
- Markup JSX
- Gestione delle varianti (fisse, brevi, sempre compresse, in evidenza)
L'approccio
- Implementa i metodi Adapter.
- Inizializza la base in
componentDidMount
. - Chiama il metodo Foundation.destroy in
componentWillUnmount
. - Stabilisci la gestione delle varianti tramite un metodo getter che combina i nomi delle classi appropriati.
4. Implementa i metodi dell'adattatore
Il Componente TopAppBar
JS non framework implementa i seguenti metodi Adapter (elencati in dettaglio qui):
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
Poiché React ha eventi sintetici e diversi pattern e best practice di codifica, i metodi Adapter devono essere reimplementati.
Metodo accessore dell'adattatore
Nel file TopAppBar.js
, aggiungi il seguente metodo JavaScript a TopAppBar
:
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,
};
}
Le API di adattamento per la registrazione degli eventi di scorrimento e ridimensionamento sono implementate in modo identico alla versione JS non del framework, perché React non dispone di eventi sintetici per lo scorrimento o il ridimensionamento e rimanda al sistema di eventi DOM nativo. getViewPortScrollY
deve anche fare riferimento al DOM nativo perché è una funzione dell'oggetto window
, che non è presente nell'API di React. Le implementazioni degli adattatori saranno diverse per ogni framework.
Potresti notare che manca this.setStyle
, che viene chiamato dal metodo get adapter
. Nel file TopAppBar.js
, aggiungi il metodo JavaScript mancante alla classe TopAppBar
:
setStyle = (varName, value) => {
const updatedStyle = Object.assign({}, this.state.style);
updatedStyle[varName] = value;
this.setState({style: updatedStyle});
}
Hai appena implementato l'adattatore. Tieni presente che a questo punto potresti visualizzare errori nella console perché l'implementazione completa non è ancora stata completata. La prossima sezione illustra come aggiungere e rimuovere le classi CSS.
5. Implementa metodi Component
Gestione di varianti e corsi
React non ha un'API per gestire le classi. Per simulare i metodi di aggiunta/rimozione delle classi CSS di JavaScript nativo, aggiungi la variabile di stato classList
. Ci sono tre porzioni di codice in TopAppBar
che interagiscono con le classi CSS:
<TopAppBar />
tramite la proprietàclassName
.- Il metodo Adapter tramite
addClass
oremoveClass
. - Hard coded all'interno del componente React
<TopAppBar />
.
Innanzitutto, aggiungi la seguente importazione nella parte superiore di TopAppBar.js
, sotto le importazioni esistenti:
import classnames from 'classnames';
Aggiungi il seguente codice all'interno della dichiarazione di classe del componente 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,
});
}
...
}
Se vai alla pagina http://localhost:8080, le caselle di controllo Controlli ora dovrebbero attivare/disattivare i nomi delle classi dal DOM.
Questo codice rende TopAppBar
utilizzabile da molti sviluppatori. Gli sviluppatori possono interagire con l'API TopAppBar
senza preoccuparsi dei dettagli di implementazione delle classi CSS.
Hai implementato correttamente l'adattatore. La sezione successiva illustra la procedura di creazione di un'istanza di Foundation.
Montaggio e smontaggio del componente
L'inizializzazione di Foundation avviene nel metodo componentDidMount
.
Innanzitutto, importa le basi della barra delle app superiore MDC aggiungendo la seguente importazione dopo le importazioni esistenti in TopAppBar.js
:
import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';
Aggiungi il seguente codice JavaScript alla classe 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();
}
...
}
Una buona pratica di codifica di React è definire propTypes e defaultProps. Aggiungi la seguente importazione dopo le importazioni esistenti in TopAppBar.js:
import PropTypes from 'prop-types';
Quindi, aggiungi il seguente codice in fondo a TopAppBar.js
(dopo la classe Componente):
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,
};
Hai implementato correttamente il componente React della barra delle app superiore. Se visiti la pagina http://localhost:8080, puoi interagire con la pagina demo. La pagina di demo funzionerà come la pagina di demo di MDC Web. La pagina di demo dovrebbe avere il seguente aspetto:
6. Conclusione
In questo tutorial abbiamo spiegato come eseguire il wrapping di Foundation di MDC Web per utilizzarlo in un'applicazione React. Su GitHub e npm sono disponibili alcune librerie che avvolgono i componenti web MDC come descritto in Integrazione nei framework. Ti consigliamo di utilizzare l'elenco disponibile qui. Questo elenco include anche altri framework oltre a React, come Angular e Vue.
Questo tutorial mette in evidenza la nostra decisione di suddividere il codice web di MDC in tre parti: Foundation, Adapter e Component. Questa architettura consente ai componenti di condividere codice comune lavorando con tutti i framework. Grazie per aver provato Material Components React. Dai un'occhiata alla nostra nuova libreria MDC React. Speriamo che questo codelab ti sia piaciuto.