لمحة عن هذا الدرس التطبيقي حول الترميز
1. مقدمة
تساعد مكونات Material Design (MDC) المطوّرين في تنفيذ أسلوب Material Design. تم إنشاء MDC من قِبل فريق من المهندسين ومصممي تجربة المستخدم في Google، ويضمّ عشرات مكوّنات واجهة المستخدم الجميلة والوظيفية، وهو متاح لنظام التشغيل Android وiOS والويب وFlutter.material.io/develop |
تم تصميم MDC Web للدمج في أي إطار عمل للواجهة الأمامية مع الالتزام بمبادئ التصميم المتعدد الأبعاد. يرشدك الدرس التطبيقي التالي حول الترميز خلال عملية إنشاء مكوِّن React الذي يستخدم MDC Web كأساس. يمكن تطبيق المبادئ المذكورة في هذا الدرس التطبيقي حول الترميز على أي إطار عمل JavaScript.
طريقة إنشاء MDC Web
تتكوّن طبقة JavaScript في MDC Web من ثلاث فئات لكل مكوّن: المكوّن والأساس والمحوِّل. يوفّر هذا النمط لـ MDC Web المرونة في الدمج مع إطارات عمل الواجهة الأمامية.
يحتوي التصميم الأساسي على منطق النشاط التجاري الذي ينفِّذ التصميم المتعدّد الأبعاد. لا يشير الأساس إلى أي عناصر HTML. ويسمح لنا ذلك بتجريد منطق تفاعل HTML في المحوّل. يحتوي النظام الأساسي على محوِّل.
المحوِّل هو واجهة. تتم الإشارة إلى واجهة Adapter من خلال المؤسسة لتنفيذ منطق النشاط التجاري في Material Design. يمكنك تنفيذ المحوِّل في إطارات عمل مختلفة، مثل Angular أو React. يتفاعل أحد عناصر التنفيذ في أداة التحويل مع بنية نموذج DOM.
المكوّن له مؤسسة، ويتمثل دوره في
- تنفيذ المحوِّل باستخدام JavaScript غير المستند إلى إطار عمل
- توفير الطرق العامة التي تعمل كخادم وكيل للطرق في المؤسسة.
الميزات التي يوفّرها MDC Web
تتضمّن كل حزمة في MDC Web مكوّنًا وقاعدة ومحوِّلًا. لإنشاء مثيل للمكوّن، يجب تمرير العنصر الجذر إلى طريقة إنشاء المكوّن. ينفِّذ المكوّن محوِّلًا يتفاعل مع عناصر DOM وHTML. بعد ذلك، ينشئ المكوّن مثيلًا لـ القاعدة، التي تستدعي طرق المحوِّل.
لدمج MDC Web في إطار عمل، عليك إنشاء مكوّن خاص بك بلغة/بنية هذا الإطار. ينفِّذ المكوّن في إطار العمل المحوِّل في MDC Web ويستخدم القاعدة في MDC Web.
ما الذي ستنشئه
يوضّح هذا الدرس التطبيقي حول الترميز كيفية إنشاء محوِّل مخصّص لاستخدام منطق القاعدة من أجل إنشاء مكوّن React لتصميم Material Design. ويتناول الموضوعات المتقدّمة الواردة في الدمج في إطارات العمل. يتم استخدام React في هذا الدليل التعليمي كإطار عمل نموذجي، ولكن يمكن تطبيق هذا النهج على أي إطار عمل آخر.
في هذا الدرس التطبيقي حول الترميز، ستنشئ "شريط التطبيقات الأفضل" وتعيد إنشاء صفحة تجريبية لشريط التطبيق العلوي. تم إعداد تنسيق الصفحة التجريبية حتى تتمكّن من بدء العمل على شريط التطبيقات العلوي. سيتضمّن شريط التطبيقات العلوي ما يلي:
- رمز التنقّل
- عناصر العمل
- تتوفّر 4 خيارات مختلفة: قصير ومصغَّر دائمًا وثابت وبارز.
المتطلبات:
- إصدار حديث من Node.js (الذي يأتي مُدمجًا مع npm، وهو مدير حِزم JavaScript)
- نموذج الرمز (سيتم تنزيله في الخطوة التالية)
- معرفة أساسية بلغات HTML وCSS وJavaScript وReact
ما هو تقييمك لمستوى خبرتك في تطوير الويب؟
2. إعداد بيئة المطوّر
تنزيل تطبيق الدرس التطبيقي الأوّلي
يمكن العثور على التطبيق المبدئي في دليل 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-components-web-codelabs/mdc-112/starter
، شغِّل:
npm install
ستلاحظ الكثير من الأنشطة، وفي النهاية، من المفترض أن يعرض جهاز الطرفية عملية تثبيت ناجحة:
تشغيل تطبيق البدء
في الدليل نفسه، نفِّذ ما يلي:
npm start
سيتم تفعيل webpack-dev-server
. اضبط متصفّحك على http://localhost:8080/ لعرض الصفحة.
اكتمال عملية النقل بنجاح يجب أن يكون رمز التشغيل لصفحة "الإصدار التجريبي من شريط التطبيقات العلوي" المستند إلى React قيد التشغيل في المتصفّح. من المفترض أن يظهر لك جدار من نص lorem ipsum ومربّع عناصر التحكّم (في أسفل يسار الصفحة) وشريط التطبيقات العلوي غير المكتمل:
الاطّلاع على الرمز البرمجي والمشروع
إذا فتحت محرِّر الرموز البرمجية، من المفترض أن يظهر دليل المشروع على النحو التالي:
افتح الملف App.js
واطّلِع على طريقة 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
الذي يمثّل فئة Component
فارغة في React مع طريقة render
:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. تركيب المكوّن
في React، تُخرج الطريقة render
رمز HTML للمكوّن. سيعرِض مكوّن Top AppBar علامة <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
- إدارة الصيغ (ثابتة، قصيرة، مصغّرة دائمًا، بارزة)
المنهجية
- نفِّذ طرق المحوِّل.
- اضبط الأساس في
componentDidMount
. - استخدِم الطريقة Foundation.destroy في
componentWillUnmount
. - يمكنك إنشاء إدارة الصيغ من خلال طريقة جلب تجمع أسماء الفئات المناسبة.
4. تنفيذ طرق Adapter
ينفِّذ TopAppBar
المكوِّن غير المستنِد إلى إطار عمل JavaScript طرق المحوِّل التالية (المُدرَجة بالتفصيل هنا):
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
بما أنّ React يتضمّن أحداثًا اصطناعية وأفضل ممارسات وترميزات وأنماطًا مختلفة، يجب إعادة تنفيذ طرق Adapter.
طريقة الحصول على المُحوِّل
في ملف 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,
};
}
يتم تنفيذ واجهات برمجة التطبيقات الخاصة بالمحوِّل لتسجيل أحداث التمرير وتغيير الحجم بشكلٍ مطابق لإصدار JavaScript غير المستنِد إلى إطار عمل، لأنّ React لا يحتوي على أي حدث اصطناعي للتمرير أو تغيير الحجم، بل يعتمد على نظام أحداث DOM الأصلي. يجب أيضًا أن تُحيل دالة getViewPortScrollY
إلى عنصر DOM الأصلي لأنّها دالة في عنصر window
، وهو ليس مضمّنًا في واجهة برمجة تطبيقات 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. لمحاكاة طرق إضافة/إزالة فئة CSS في JavaScript الأصلي، أضِف متغيّر الحالة classList
. هناك ثلاث قطع من الرمز في TopAppBar
تتفاعل مع فئات CSS:
- المكوِّن "
<TopAppBar />
" من خلال ميزة "className
". - طريقة المحوِّل من خلال
addClass
أوremoveClass
- تمّ تضمينها بشكلٍ ثابت في
<TopAppBar />
React Component.
أولاً، أضِف عملية الاستيراد التالية في أعلى TopAppBar.js
، أسفل عمليات الاستيراد الحالية:
import classnames from 'classnames';
بعد ذلك، أضِف الرمز البرمجي التالي داخل بيان فئة TopAppBar
Component:
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
. يمكن للمطوّرين التفاعل مع واجهة برمجة التطبيقات TopAppBar
بدون القلق بشأن تفاصيل تنفيذ فئات CSS.
لقد نجحت الآن في تنفيذ المكوّن الإضافي. سيرشدك القسم التالي خلال إنشاء مثيل لمؤسسة.
تحميل المكوّن وإلغاء تحميله
يتم إنشاء مثيل 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,
};
لقد أكملت الآن مكوِّن Top App Bar React بنجاح. عند الانتقال إلى http://localhost:8080، يمكنك الانتقال إلى صفحة العرض التوضيحي. ستتّبع صفحة العرض النموذجي آلية عمل صفحة العرض النموذجي لخدمة MDC Web. من المفترض أن تظهر صفحة العرض على النحو التالي:
6. الخاتمة
في هذا الدليل التعليمي، اطّلعنا على كيفية لف Foundation في MDC Web لاستخدامه في تطبيق React. هناك بعض المكتبات على GitHub وnpm التي تلتف مكونات الويب MDC كما هو موضّح في الدمج في إطارات العمل. ننصحك باستخدام القائمة الواردة هنا. تتضمّن هذه القائمة أيضًا إطارات عمل أخرى غير React، مثل Angular وVue.
يوضّح هذا الدليل التعليمي قرارنا بتقسيم رمز MDC Web إلى 3 أجزاء، وهي الأساس والمحوِّل والمكوّن. تسمح هذه البنية للمكوّنات بمشاركة الرمز البرمجي المشترك أثناء العمل مع جميع الإطارات الأساسية. نشكرك على تجربة Material Components React، وننصحك بالاطّلاع على مكتبتنا الجديدة MDC React. نأمل أنّك استفدت من هذا الدرس التطبيقي حول الترميز.