מידע על Codelab זה
1. מבוא
Material Components (MDC) עוזר למפתחים להטמיע Material Design. MDC נוצר על ידי צוות של מהנדסים ומעצבי חוויית המשתמש ב-Google, שכולל עשרות רכיבים יפים ופונקציונליים של ממשק המשתמש. זמין ל-Android, ל-iOS, לאינטרנט ול-Flutter.material.io/develop |
MDC Web מתוכנן לשילוב בכל framework של קצה קדמי תוך שמירה על העקרונות של Material Design. ב-Codelab הבא מוסבר איך לבנות רכיב React, שמשתמש ב-MDC Web כבסיס. אפשר ליישם את העקרונות שנלמדו ב-Codelab הזה על כל מסגרת JavaScript.
איך בנוי MDC Web
שכבת ה-JavaScript ב-MDC Web מורכבת משלושה מחלקות לכל רכיב: הרכיב, הבסיס ו-המתאם. הדפוס הזה נותן ל-MDC Web את הגמישות לשילוב עם frameworks של קצה קדמי.
הבסיס כולל את הלוגיקה העסקית שמטמיעה עיצוב חדשני (Material Design). הבסיס אינו מפנה לרכיבי HTML. כך נוכל להפשט לוגיקה של אינטראקציות HTML ב-Adapter. לבסיס יש מתאם.
המתאם הוא ממשק. הבסיס מפנה לממשק המתאם כדי להטמיע לוגיקה עסקית של Material Design. אפשר להטמיע את המתאם במסגרות שונות, כמו Angular או React. הטמעה של מתאם מקיימת אינטראקציה עם מבנה ה-DOM.
לרכיב יש בסיס, והתפקיד שלו הוא
- מטמיעים את ה-Adapter באמצעות JavaScript שאינו framework, וגם
- מציינים שיטות ציבוריות שמשמשות ל-methods בבסיס.
מה יש ב-MDC Web
כל חבילה ב-MDC Web מגיעה עם רכיב, יסודות ומתאם. כדי ליצור רכיב, צריך להעביר את הרכיב הבסיסי (root) ל-method של ה-constructor של הרכיב. הרכיב מיישם מתאם, שמקיים אינטראקציה עם רכיבי ה-DOM וה-HTML. לאחר מכן, הרכיב יוצר את ה-Foundation, שנקרא ל-methods של מתאם.
כדי לשלב את MDC Web ב-framework, אתם צריכים ליצור רכיב משלכם בשפה או בתחביר של המסגרת הזו. הרכיב של ה-framework מיישם את Adapter של MDC Web ומשתמש בבסיס של MDC Web.
מה תפַתחו
ה-Codelab הזה מדגים איך לפתח מתאם בהתאמה אישית להשתמש בלוגיקת Foundation כדי להשיג רכיב React React. הוא כולל את הנושאים המתקדמים שזמינים במאמר שילוב ב-frames. משתמשים ב-React ב-Codelab הזה כ-framework לדוגמה, אבל אפשר להחיל את הגישה הזו על כל framework אחרת.
ב-Codelab הזה, תצרו את סרגל האפליקציות המוביל ותצרו מחדש את דף ההדגמה של סרגל האפליקציות העליון. הפריסה של דף ההדגמה כבר מוגדרת, כך שאפשר להתחיל לעבוד על סרגל האפליקציות העליון. סרגל האפליקציות העליון יכלול את:
- סמל הניווט
- פעולות לביצוע
- יש 4 וריאציות זמינות: וריאציה קצרה, תמיד מכווצת, קבועה ובולטת
מה צריך:
- גרסה עדכנית של Node.js (שנשלחת בחבילה עם npm, מנהל חבילות של JavaScript)
- הקוד לדוגמה (להורדה בשלב הבא)
- ידע בסיסי ב-HTML, ב-CSS, ב-JavaScript וב-React
איזה דירוג מגיע לדעתך לרמת הניסיון שלך בפיתוח אתרים?
2. הגדרה של סביבת הפיתוח
להורדה של אפליקציית Codelab למתחילים
האפליקציה לתחילת הפעולה נמצאת בספרייה material-components-web-codelabs-master/mdc-112/starter
.
...או לשכפל אותו מ-GitHub
כדי לשכפל את ה-Codelab הזה מ-GitHub, מריצים את הפקודות הבאות:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
תלות של פרויקטים בהתקנות
מספריית המתחילים material-components-web-codelabs/mdc-112/starter
, מריצים את:
npm install
יש פעילות רבה ובסופה, ההתקנה אמורה להופיע בטרמינל:
הפעלת אפליקציה לתחילת פעולה
באותה ספרייה, מריצים את:
npm start
webpack-dev-server
יתחיל. מכוונים את הדפדפן אל http://localhost:8080/ כדי לראות את הדף.
הצלחת! קוד הסימן לתחילת הפעולה של דף ה'הדגמה של סרגל האפליקציות העליון' אמור לפעול בדפדפן. אתם אמורים לראות קיר עם הטקסט lorem ipsum, תיבת Controls (בפינה השמאלית התחתונה) וסרגל אפליקציות עליון לא גמור:
צפייה בקוד ובפרויקט
אם פותחים את עורך הקוד, ספריית הפרויקט אמורה להיראות בערך כך:
פותחים את הקובץ App.js
ומעיינים ב-method render
, שכוללת את הרכיב <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>
);
}
זוהי נקודת הכניסה של TopAppBar
באפליקציה.
פותחים את הקובץ TopAppBar.js
, שהוא מחלקה של React Component
באמצעות method render
:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. הרכב הרכיב
ב-React, ה-method render
מפיקה את ה-HTML של הרכיב. רכיב סרגל האפליקציות העליון יעביר תג <header />
ויורכב מ-2 קטעים ראשיים:
- סמל הניווט וקטע הכותרת
- קטע של סמלי פעולות
אם יש לכם שאלות לגבי הרכיבים שמרכיבים את סרגל האפליקציות המוביל, כדאי לעיין במסמכי התיעוד ב-GitHub.
משנים את ה-method 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
, שנעשה בה שימוש ב-method render
. צריך להוסיף את שיטת ה-JavaScript הבאה למחלקה TopAppBar
:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
גם this.classes
חסר בשיטה render
, אבל הוא יופיע בקטע מאוחר יותר. חוץ משיטת getter החסרה, this.classes
, יש עדיין חלקים מה-TopAppBar
שצריך להטמיע כדי שסרגל האפליקציה העליון יוכל לעבד כראוי.
החלקים ברכיב React שעדיין חסרים בסרגל האפליקציות העליון הם:
- תשתית התחלתית
- שיטות מתאמים להעברה
- תגי עיצוב של JSX
- ניהול וריאציות (קבוע, קצר, תמיד מכווץ, בולט)
הגישה
- מטמיעים את השיטות Adapter.
- צריך לאתחל את הבסיס ב-
componentDidMount
. - קוראים ל-method Foundation.destroy ב-
componentWillUnmount
. - להגדיר ניהול וריאנטים באמצעות שיטת getter שמשלבת שמות של מחלקות מתאימים.
4. הטמעת שיטות של מתאם
הרכיב TopAppBar
של JS ללא מסגרת מטמיע את שיטות המתאם הבאות (מפורטות כאן):
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
ב-React יש אירועים סינתטיים ושיטות קידוד מומלצות ושיטות תכנות מומלצות שונות, לכן צריך להטמיע מחדש את השיטות של המתאם.
שיטת Getter של מתאם
בקובץ TopAppBar.js
, צריך להוסיף את שיטת ה-JavaScript הבאה ל-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,
};
}
ממשקי ה-API של המתאמים לרישום אירועים בגלילה ושינוי הגודל מוטמעים באופן זהה לגרסת ה-JS שאינה של framework, כי ב-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
. - ה-method Adapter דרך
addClass
אוremoveClass
. - מופיע בתוך הקוד ברכיב
<TopAppBar />
React.
קודם כול צריך להוסיף את הייבוא הבא בחלק העליון של 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.
הטמעתם בהצלחה את המתאם. בקטע הבא מוסבר איך ליצור בסיס.
טעינה וניתוק של הרכיב
יצירת הבסיס מתרחשת בשיטה 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 היא להגדיר profTypes ו-defaultProps. אחרי פעולות הייבוא הקיימות ב-TopAppBar.js, צריך להוסיף את הייבוא הבא:
import PropTypes from 'prop-types';
לאחר מכן מוסיפים את הקוד הבא לתחתית של TopAppBar.js
(אחרי מחלקת הרכיבים):
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,
};
הטמעת בהצלחה את רכיב התגובה העליונה של האפליקציה. אם מנווטים אל http://localhost:8080 אפשר לשחק בדף ההדגמה. דף ההדגמה יפעל בדיוק כמו דף ההדגמה של MDC Web. דף ההדגמה אמור להיראות כך:
6. סיכום
במדריך הזה למדנו איך לארוז את הבסיס של MDC Web לשימוש באפליקציית React. יש כמה ספריות ב-GitHub וב-npm שעורזות את רכיבי MDC באינטרנט, כמו שמתואר במאמר שילוב לתוך Frameworks. מומלץ להשתמש ברשימה שמופיעה כאן. הרשימה הזו כוללת גם frameworks אחרות, מלבד React, כמו Angular ו-Vue.
במדריך הזה נדגיש את ההחלטה שלנו לפצל את קוד האינטרנט של MDC ל-3 חלקים: הבסיס, המתאם והרכיב. הארכיטקטורה הזו מאפשרת לרכיבים לשתף קוד משותף תוך כדי עבודה עם כל ה-frameworks. תודה שניסית את Material Materials React. כדאי להציץ בספרייה החדשה שלנו MDC React. אנחנו מקווים שנהניתם מה-Codelab הזה!