Web MDC-112: Mengintegrasikan MDC dengan Framework Web

Web MDC-112:
Mengintegrasikan MDC dengan Framework Web

Tentang codelab ini

subjectTerakhir diperbarui Okt 11, 2020
account_circleDitulis oleh Liz Mitchell, Abhinay Omkar

1. Pengantar

logo_components_color_2x_web_96dp.png

Komponen Material (MDC) membantu developer menerapkan Desain Material. Dibuat oleh tim engineer dan desainer UX di Google, MDC memiliki banyak komponen UI yang indah dan fungsional serta tersedia untuk Android, iOS, web, dan Flutter.material.io/develop

Web MDC dirancang untuk berintegrasi ke dalam framework front end apa pun dengan tetap menegakkan prinsip Desain Material. Codelab berikut memandu Anda dalam membangun Komponen React, yang menggunakan Web MDC sebagai fondasi. Prinsip yang dipelajari dalam codelab ini dapat diterapkan ke framework JavaScript apa pun.

Cara Web MDC dibuat

Lapisan JavaScript Web MDC terdiri dari tiga class per komponen: Komponen, Foundation, dan Adaptor. Pola ini memberi MDC Web fleksibilitas untuk berintegrasi dengan framework frontend.

Foundation berisi logika bisnis yang menerapkan Desain Material. Dasar ini tidak mereferensikan elemen HTML apa pun. Tindakan ini memungkinkan kita memisahkan logika interaksi HTML ke dalam Adapter. Foundation memiliki Adapter.

Adapter adalah antarmuka. Antarmuka Adaptor dirujuk oleh Foundation untuk menerapkan logika bisnis Desain Material. Anda dapat menerapkan Adapter di berbagai framework seperti Angular atau React. Implementasi Adaptor berinteraksi dengan struktur DOM.

Komponen memiliki Fondasi, dan perannya adalah untuk

  1. Implementasikan Adapter, menggunakan JavaScript non-framework, dan
  2. Sediakan metode publik yang melakukan proxy ke metode di Foundation.

Yang disediakan MDC Web

Setiap paket di Web MDC dilengkapi dengan Komponen, Foundation, dan Adaptor. Untuk membuat instance Komponen, Anda harus meneruskan elemen root ke metode konstruktor Komponen. Komponen menerapkan Adapter, yang berinteraksi dengan elemen DOM dan HTML. Komponen kemudian membuat instance Foundation, yang memanggil metode Adapter.

Untuk mengintegrasikan MDC Web ke dalam framework, Anda harus membuat Komponen sendiri dalam bahasa/sintaksis framework tersebut. Framework Komponen menerapkan Adapter Web MDC dan menggunakan Foundation MDC Web.

Yang akan Anda bangun

Codelab ini menunjukkan cara membuat Adapter kustom untuk menggunakan logika Foundation guna mencapai Komponen React Desain Material. Panduan ini mencakup topik lanjutan yang terdapat dalam artikel Mengintegrasikan ke Framework. React digunakan dalam codelab ini sebagai contoh framework, tetapi pendekatan ini dapat diterapkan ke framework lainnya.

Dalam codelab ini, Anda akan membangun Panel Aplikasi Atas dan membuat ulang halaman demo panel aplikasi atas. Tata letak halaman demo sudah disiapkan sehingga Anda dapat mulai bekerja di Panel Aplikasi Atas. Panel Aplikasi Atas akan mencakup:

  • Ikon navigasi
  • Item tindakan
  • Ada 4 varian yang tersedia: varian Singkat, selalu diciutkan, tetap, dan jelas

Yang Anda butuhkan:

  • Versi terbaru Node.js (yang dilengkapi dengan npm, pengelola paket JavaScript)
  • Kode contoh (akan didownload pada langkah berikutnya)
  • Pengetahuan dasar tentang HTML, CSS, JavaScript, dan React

Bagaimana Anda menilai tingkat pengalaman Anda dengan pengembangan web?

2. Menyiapkan lingkungan pengembangan

Mendownload aplikasi codelab awal

Aplikasi awal terletak di direktori material-components-web-codelabs-master/mdc-112/starter.

...atau meng-clone codelab dari GitHub

Untuk meng-clone codelab ini dari GitHub, jalankan perintah berikut:

git clone https://github.com/material-components/material-components-web-codelabs
cd material
-components-web-codelabs/mdc-112/starter

Menginstal dependensi project

Dari direktori awal material-components-web-codelabs/mdc-112/starter, jalankan:

npm install

Anda akan melihat banyak aktivitas dan di akhir, terminal Anda akan menunjukkan penginstalan yang berhasil:

22a33efc2a687408.png

Menjalankan aplikasi awal

Dalam direktori yang sama, jalankan:

npm start

webpack-dev-server akan dimulai. Arahkan browser ke http://localhost:8080/ untuk melihat halaman.

b55c66dd400cf34f.png

Berhasil! Kode awal untuk halaman Demo React Panel Aplikasi Teratas harus berjalan di browser Anda. Anda akan melihat dinding teks lorem ipsum, kotak Controls (kanan bawah), dan Panel Aplikasi Atas yang belum selesai:

4ca3cf6d216f9290.pngS

Melihat kode dan project

Jika Anda membuka editor kode, direktori project akan terlihat seperti ini:

e9a3270d6a67c589.png

Buka file App.js dan lihat metode render yang menyertakan Komponen <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>
    );
  }

Ini adalah titik entri untuk TopAppBar dalam aplikasi.

Buka file TopAppBar.js yang merupakan class React Component sederhana dengan metode render:

TopAppBar.js

import React from 'react';

export default class TopAppBar extends React.Component {
 
render() {
   
return (
     
<header>
       
TOP APP BAR
     
</header>
   
);
 
}
}

3. Komposisi komponen

Di React, metode render menghasilkan output HTML Komponen. Komponen Panel Aplikasi Atas akan merender tag <header />, dan akan terdiri dari 2 bagian utama:

  1. Ikon navigasi dan bagian judul
  2. Bagian ikon tindakan

Jika ada pertanyaan tentang elemen yang membentuk Panel Aplikasi Atas, buka dokumentasi di GitHub.

Ubah metode render() di TopAppBar.js agar terlihat seperti ini:

  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>
    );
  }

Ada dua elemen bagian dalam HTML ini. Yang pertama berisi ikon dan judul navigasi. Yang kedua berisi ikon tindakan.

Selanjutnya, tambahkan metode 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>
  );
}

Developer akan mengimpor TopAppBar ke dalam aplikasi React-nya dan meneruskan ikon tindakan ke elemen TopAppBar. Anda dapat melihat kode contoh yang melakukan inisialisasi TopAppBar di App.js.

Metode getMergedStyles tidak ada, yang digunakan dalam metode render. Tambahkan metode JavaScript berikut ke class TopAppBar:

getMergedStyles = () => {
  const {style} = this.props;
  const {style: internalStyle} = this.state;
  return Object.assign({}, internalStyle, style);
}

this.classes juga tidak ada di metode render, tetapi akan dibahas di bagian selanjutnya. Selain metode pengambil yang tidak ada, this.classes, masih ada bagian TopAppBar yang perlu Anda terapkan sebelum Panel Aplikasi Atas dapat dirender dengan benar.

Bagian dari Komponen React yang masih belum ada di Panel Aplikasi Atas adalah:

  • Fondasi yang diinisialisasi
  • Metode adaptor untuk diteruskan ke fondasi
  • Markup JSX
  • Pengelolaan varian (tetap, singkat, selalu diciutkan, terlihat)

Pendekatan

  1. Terapkan metode Adapter.
  2. Lakukan inisialisasi Foundation di componentDidMount.
  3. Panggil metode Foundation.destroy di componentWillUnmount.
  4. Menetapkan pengelolaan varian melalui metode pengambil yang menggabungkan nama class yang sesuai.

4. Mengimplementasikan metode Adaptor

Komponen TopAppBar JS non-framework menerapkan metode Adapter berikut (tercantum secara detail di sini):

  • hasClass()
  • addClass()
  • removeClass()
  • registerNavigationIconInteractionHandler()
  • deregisterNavigationIconInteractionHandler()
  • notifyNavigationIconClicked()
  • setStyle()
  • getTopAppBarHeight()
  • registerScrollHandler()
  • deregisterScrollHandler()
  • registerResizeHandler()
  • deregisterResizeHandler()
  • getViewportScrollY()
  • getTotalActionItems()

Karena React memiliki peristiwa sintetis serta berbagai praktik dan pola coding terbaik, metode Adapter perlu diterapkan kembali.

Metode Pengambil Adaptor

Di file TopAppBar.js, tambahkan metode JavaScript berikut ke 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 adaptor untuk pendaftaran peristiwa scroll dan ubah ukuran diterapkan secara identik dengan versi JS non-framework, karena React tidak memiliki peristiwa sintetis untuk men-scroll atau mengubah ukuran dan tunduk pada sistem peristiwa DOM native. getViewPortScrollY juga harus tunduk pada DOM native karena merupakan fungsi di objek window, yang tidak ada di API React. Implementasi adaptor akan berbeda untuk setiap framework.

Anda mungkin melihat this.setStyle tidak ada, yang dipanggil oleh metode get adapter. Di file TopAppBar.js, tambahkan metode JavaScript yang tidak ada ke class TopAppBar:

setStyle = (varName, value) => {
  const updatedStyle = Object.assign({}, this.state.style);
  updatedStyle[varName] = value;
  this.setState({style: updatedStyle});
}

Anda baru saja mengimplementasikan Adaptor. Perhatikan bahwa Anda mungkin melihat error di konsol pada tahap ini karena implementasi penuh belum selesai. Bagian berikutnya akan memandu Anda terkait cara menambahkan dan menghapus class CSS.

5. Mengimplementasikan metode Komponen

Mengelola Varian dan Class

React tidak memiliki API untuk mengelola class. Untuk meniru metode class tambahkan/hapus pada JavaScript native, tambahkan variabel status classList. Ada tiga bagian kode di TopAppBar yang berinteraksi dengan class CSS:

  1. Komponen <TopAppBar /> melalui properti className.
  2. Metode Adapter melalui addClass atau removeClass.
  3. Hard code dalam Komponen React <TopAppBar />.

Pertama, tambahkan impor berikut di bagian atas TopAppBar.js, di bawah impor yang ada:

import classnames from 'classnames';

Lalu, tambahkan kode berikut di dalam deklarasi class Komponen 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,
    });
  }

  ...
}

Jika Anda membuka http://localhost:8080, kotak centang Kontrol sekarang akan mengaktifkan/menonaktifkan nama class dari DOM.

Kode ini membuat TopAppBar dapat digunakan oleh banyak developer. Developer dapat berinteraksi dengan TopAppBar API, tanpa perlu mengkhawatirkan detail implementasi class CSS.

Anda telah berhasil menerapkan Adaptor. Bagian berikutnya akan memandu Anda membuat instance Fondasi.

Memasang dan Melepas Komponen

Pembuatan instance fondasi terjadi dalam metode componentDidMount.

Pertama, impor fondasi Panel Aplikasi Atas MDC dengan menambahkan impor berikut setelah impor yang ada di TopAppBar.js:

import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';

Selanjutnya, tambahkan kode JavaScript berikut ke dalam class 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();
  }
 
  ...

}

Salah satu praktik coding React yang baik adalah menentukan propTypes dan defaultProps. Tambahkan impor berikut setelah impor yang ada di TopAppBar.js:

import PropTypes from 'prop-types';

Kemudian, tambahkan kode berikut ke bagian bawah TopAppBar.js (setelah class Komponen):

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,
};

Anda kini telah berhasil menerapkan Komponen Reaksi Panel Aplikasi Teratas. Jika membuka http://localhost:8080, Anda dapat mencoba halaman demo. Halaman demo akan berfungsi sama seperti halaman demo MDC Web. Halaman demo akan terlihat seperti ini:

3d983b98c2092e7a.pngS

6. Rangkuman

Dalam tutorial ini, kita telah membahas cara menggabungkan Fondasi Web MDC untuk digunakan dalam aplikasi React. Ada beberapa library di GitHub dan npm yang menggabungkan Komponen Web MDC seperti yang dijelaskan dalam Mengintegrasikan ke Framework. Sebaiknya gunakan daftar yang ada di sini. Daftar ini juga menyertakan framework lain selain React seperti Angular dan Vue.

Tutorial ini menyoroti keputusan kami untuk membagi kode Web MDC menjadi 3 bagian, yaitu Foundation, Adapter, dan Komponen. Arsitektur ini memungkinkan komponen untuk berbagi kode umum saat bekerja dengan semua framework. Terima kasih telah mencoba React Komponen Material dan lihat library baru kami MDC React. Kami harap Anda menikmati codelab ini.

Saya dapat menyelesaikan codelab ini dengan upaya dan dalam durasi waktu yang wajar

Saya ingin terus menggunakan Komponen Material pada masa mendatang