MDC-112 Web: دمج MDC مع أطر عمل الويب

1. مقدمة

logo_components_color_2x_web_96dp.png

تساعد Material Components (MDC) المطوّرين في تنفيذ التصميم المتعدد الأبعاد. تم إنشاء MDC بواسطة فريق من المهندسين ومصممي تجربة المستخدم في Google، وتتضمّن عشرات المكوّنات الجميلة والوظيفية لواجهة المستخدم، وهي متاحة على Android وiOS والويب وFlutter.material.io/develop

تم تصميم MDC Web ليتكامل مع أي إطار عمل للواجهة الأمامية مع الالتزام بمبادئ التصميم المتعدد الأبعاد. يرشدك الدرس التطبيقي حول الترميز التالي إلى خطوات إنشاء مكوّن React، والذي يستخدم MDC Web كأساس. يمكن تطبيق المبادئ التي تم تعلّمها في هذا الدرس التطبيقي حول الترميز على أي إطار عمل JavaScript.

طريقة إنشاء MDC Web

تتألف طبقة JavaScript في MDC Web من ثلاث فئات لكل مكوّن: المكوّن والأساس والمحوّل. يمنح هذا النمط MDC Web المرونة اللازمة للدمج مع أُطر عمل الواجهة الأمامية.

تحتوي Foundation على منطق النشاط التجاري الذي ينفّذ التصميم المتعدد الأبعاد. لا تشير Foundation إلى أي عناصر HTML. يتيح لنا ذلك تجريد منطق التفاعل مع HTML إلى Adapter. يحتوي Foundation على محوّل.

Adapter هي واجهة. تشير Foundation إلى واجهة Adapter لتنفيذ منطق نشاط التصميم المتعدد الأبعاد التجاري. يمكنك تنفيذ Adapter في أُطر مختلفة، مثل Angular أو React. يتفاعل تنفيذ المحوّل مع بنية نموذج العناصر في المستند (DOM).

يحتوي المكوّن على أساس، ودوره هو

  1. نفِّذ المحوّل باستخدام JavaScript غير المستند إلى إطار عمل،
  2. قدِّم طرقًا عامة تعمل كوكيل للطرق في Foundation.

الميزات التي يوفّرها MDC Web

تتضمّن كل حزمة في MDC Web مكوّنًا وأساسًا ومحوّلاً. لإنشاء مثيل للمكوِّن، يجب تمرير عنصر الجذر إلى طريقة وضع تصميم المكوِّن. ينفّذ المكوّن محوّلاً يتفاعل مع عناصر DOM وHTML. بعد ذلك، ينشئ المكوّن الفئة الأساسية التي تستدعي طرق المحوّل.

لدمج MDC Web في إطار عمل، عليك إنشاء مكوِّن خاص بك بلغة/بنية هذا الإطار. يُنفِّذ إطار العمل Component واجهة Adapter الخاصة بـ MDC Web ويستخدم Foundation الخاصة بـ MDC Web.

ما ستنشئه

يوضّح هذا الدرس التطبيقي حول الترميز كيفية إنشاء محوّل مخصّص لاستخدام منطق Foundation من أجل إنشاء "مكوّن React" متوافق مع "التصميم المتعدد الأبعاد". ويتناول هذا القسم المواضيع المتقدّمة الواردة في الدمج في الأُطر. يتم استخدام 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

ستلاحظ الكثير من الأنشطة، وفي النهاية، من المفترض أن تعرض لك نافذة الأوامر رسالة تفيد بنجاح عملية التثبيت:

22a33efc2a687408.png

تشغيل تطبيق المبتدئين

في الدليل نفسه، نفِّذ ما يلي:

npm start

سيبدأ webpack-dev-server. انتقِل بمتصفّحك إلى http://localhost:8080/ للاطّلاع على الصفحة.

b55c66dd400cf34f.png

اكتمال النقل بنجاح يجب أن يتم تشغيل الرمز الأولي لصفحة Top App Bar React Demo في متصفّحك. من المفترض أن يظهر لك جدار من نص lorem ipsum ومربّع عناصر التحكّم (في أسفل يسار الصفحة) وشريط تطبيق علوي غير مكتمل:

4ca3cf6d216f9290.png

إلقاء نظرة على الرمز البرمجي والمشروع

إذا فتحت أداة تعديل الرموز البرمجية، من المفترض أن يبدو دليل المشروع على النحو التالي:

e9a3270d6a67c589.png

افتح الملف 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 الذي يمثّل فئة React Component بسيطة تتضمّن طريقة 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 الخاص بالمكوّن. سيعرض مكوّن شريط التطبيق العلوي علامة <header />، وسيتألف من قسمَين رئيسيَين:

  1. قسم رمز التنقّل والعنوان
  2. قسم رموز الإجراءات

إذا كانت لديك أسئلة حول العناصر التي يتألف منها شريط التطبيق العلوي، يمكنك الانتقال إلى المستندات على 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، ولكن سيتم تناوله في قسم لاحق. بالإضافة إلى طريقة getter المفقودة، this.classes، لا يزال هناك أجزاء من TopAppBar عليك تنفيذها قبل أن يتم عرض شريط التطبيق العلوي بشكل صحيح.

في ما يلي أجزاء مكوّن React التي لا تزال مفقودة من شريط التطبيق العلوي:

  • مؤسسة تم إعدادها
  • طُرق المحوّل التي سيتم تمريرها إلى الأساس
  • ترميز JSX
  • إدارة خيارات المنتج (ثابتة، قصيرة، يتم تصغيرها دائمًا، بارزة)

الطريقة

  1. نفِّذ طرق المحوّل.
  2. ابدأ Foundation في componentDidMount.
  3. استدعِ طريقة Foundation.destroy في componentWillUnmount.
  4. يمكنك إنشاء إدارة صيغ من خلال طريقة getter تجمع بين أسماء الفئات المناسبة.

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 API. ستختلف عمليات تنفيذ المحوّل لكل إطار عمل.

قد تلاحظ أنّ 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});
}

لقد نفّذت Adapter للتو. يُرجى العِلم أنّه قد تظهر لك أخطاء في وحدة التحكّم في هذه المرحلة لأنّ عملية التنفيذ الكاملة لم تكتمل بعد. سيرشدك القسم التالي إلى كيفية إضافة فئات CSS وإزالتها.

5- تنفيذ طرق Component

إدارة خيارات المنتجات وفئاتها

لا تتضمّن React واجهة برمجة تطبيقات لإدارة الصفوف. لمحاكاة طرق إضافة/إزالة فئة CSS في JavaScript الأصلية، أضِف متغير الحالة classList. هناك ثلاثة أجزاء من الرمز في TopAppBar تتفاعل مع فئات CSS:

  1. المكوِّن <TopAppBar /> من خلال السمة className
  2. طريقة وصلة التحويل من خلال addClass أو removeClass
  3. يتم ترميزها بشكل ثابت ضمن <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.

لقد نفّذت الآن Adapter بنجاح. سيرشدك القسم التالي إلى كيفية إنشاء مثيل Foundation.

تحميل المكوّن وإلغاء تحميله

يحدث إنشاء مثيل 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. يجب أن تبدو الصفحة التجريبية على النحو التالي:

3d983b98c2092e7a.png

6. الخاتمة

في هذا البرنامج التعليمي، تناولنا كيفية تضمين Foundation من MDC Web لاستخدامه في تطبيق React. تتوفّر بعض المكتبات على Github وnpm التي تتضمّن أغلفة لمكوّنات MDC Web، كما هو موضّح في الدمج مع أُطر العمل. ننصحك باستخدام القائمة المتوفّرة هنا. تتضمّن هذه القائمة أيضًا أُطرًا أخرى غير React، مثل Angular وVue.

يُبرز هذا البرنامج التعليمي قرارنا بتقسيم رمز MDC Web إلى 3 أجزاء، وهي Foundation وAdapter وComponent. يتيح هذا التصميم للمكوّنات مشاركة الرمز البرمجي الشائع أثناء العمل مع جميع الأُطر. شكرًا على تجربة Material Components React، ويُرجى الاطّلاع على مكتبتنا الجديدة MDC React. نأمل أن يكون هذا الدرس التطبيقي حول الترميز قد نال إعجابك.

تمكّنتُ من إكمال هذا الدرس التطبيقي حول الترميز خلال فترة زمنية معقولة وبجهد معقول

أوافق بشدة أوافق لا أوافق ولا أعارض لا أوافق لا أوافق أبدًا

أريد مواصلة استخدام "مكوّنات Material" في المستقبل

أوافق بشدة أوافق لا أوافق ولا أعارض لا أوافق لا أوافق أبدًا