マークアップと CSS の移行

学習の目的

この単元を完了すると、次のことができるようになります。
  • Aura コンポーネントから Lightning Web コンポーネントへ HTML とマークアップを移行する。
  • Aura コンポーネントから Lightning Web コンポーネントへ CSS を移行する。

DreamHouse アプリケーション

Aura コンポーンネントと Lightning Web コンポーネントのプログラミングモデルを比較する最善の方法は、2 つのモデルで記述された類似のコンポーネントのコードを見てみることです。

Lightning コンポーネントを紹介するために Salesforce が開発した DreamHouse アプリケーションという比較的複雑なアプリケーションの一部であるコンポーネントをいくつか見てみます。DreamHouse は Salesforce プラットフォーム上に構築された不動産業向けのサンプルアプリケーションです。このアプリケーションを使って、仲介担当者は物件を管理し、買主は念願のマイホームを見つけることができます。

DreamHouse アプリケーションは、Aura コンポーネントが実装されたものと、Lightning Web コンポーネントが実装されたものがあり、それぞれの完全なコードは 2 つの異なる GitHub リポジトリにあります。アプリケーションの両バージョンの機能は同じではありませんが、2 つのプログラミングモデルを比較する上で有用なコンポーネントがいくつかあります。

DreamHouse アプリケーションの 2 つの実装のコードは GitHub リポジトリにあります。

Aura コンポーネントのコードスニペットを参照し、Aura コードが Lightning Web コンポーネントコードにどのようにマッピングされるか説明します。また、Aura コンポーネントの概念が Lightning Web コンポーネントではどのように変換されるのかについても説明します。コアスニペットを中心にこれらの概念を説明します。その後、他のコンテキストに興味がある場合は、コンポーネントを調べることができます。

コンポーネントのバンドル

Aura コンポーネントと Lightning Web コンポーネントでは、コンポーネントバンドルのファイル構造が異なります。2 種類のコンポーネント間でファイルは次のようにマッピングされます。

リソース Aura のファイル Lightning Web コンポーネントのファイル
マークアップ sample.cmp sample.html
管理者 sampleController.js sample.js
ヘルパー sampleHelper.js
レンダラー sampleRenderer.js
CSS sample.css sample.css
ドキュメント sample.auradoc 現在利用できません。
設計 sample.design sample.js-meta.xml
SVG sample.svg HTML ファイルに含めるか、静的リソースとしてアップロードします。
メモ

メモ

Aura コンポーネントのコントローラ、ヘルパー、レンダラーの個別ファイルは、Lightning Web コンポーネントの 1 つの JavaScript ファイルにマッピングされます。

Lightning Web コンポーネントには HTML ファイル、JavaScript ファイル、設定ファイルを含める必要があります。省略可能な CSS ファイルと追加の JavaScript ファイルを含めることができます。

サービスコンポーネントまたはライブラリとも呼ばれる、UI を表示しないコンポーネントには、JavaScript ファイルとメタデータ設定ファイルを含める必要があります。

この単元では、HTML ファイルと CSS ファイルを見ていきます。次の単元では、JavaScript ファイルについて説明します。

Lightning Web コンポーネントにはさらに設定ファイルがあります。このファイルは、Lightning アプリケーションビルダー向けのコンポーネントのデザイン設定を含め、コンポーネントのメタデータ値を定義します。Aura コンポーネントでは、設定ファイルにはインターフェースによって定義されるメタデータ (flexipage:availableForRecordHome など) が保存されています。

マークアップの移行

Aura コンポーネントでは、マークアップは .cmp ファイルに保存されています。このファイルは <aura:component> タグで始まり、HTML および Aura 固有のタグを含めることができます。

Lightning Web コンポーネントでは、マークアップは .html ファイルに保存されています。このファイルは <template> タグで始まり、動的コンテンツの HTML とディレクティブを含めることができます。

Aura のマークアップが Lightning Web コンポーネントの HTML ファイルと JavaScript ファイルの内容にどのようにマッピングされるのか見てみましょう。

属性は JavaScript プロパティになる

Aura コンポーネントのマークアップ (.cmp) の <aura:attribute> タグの属性を、Lightning Web コンポーネントの JavaScript ファイル (.js) の JavaScript プロパティに移行します。

PropertySummary Aura コンポーネントのマークアップでこれらの属性を見てみましょう。完全なファイルは DreamHouse Aura コンポーネントの GitHub リポジトリにあります。

    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="property" type="Property__c" />

Lightning Web コンポーネントでは、マークアップの属性の代わりに JavaScript プロパティを使用します。propertySummary.js でプロパティを見てみましょう。

import { LightningElement, api } from 'lwc';
export default class PropertySummary extends LightningElement {
    @api recordId;
    property;
        ...
}

Aura コンポーネントの recordId および property 属性は、Lightning Web コンポーネントの recordId および property JavaScript プロパティになります。

@api デコレータは recordId を公開プロパティとしてマークします。公開プロパティはコンポーネントの公開 API の一部です。つまり、Lightning アプリケーションビルダー、またはマークアップでコンポーネントを使用する親コンポーネントで設定することができます。

Aura の基本的な式は HTML の式になる

Aura コンポーネントのマークアップの基本的な式を、Lightning Web コンポーネントの HTML の式に移行します。基本的な式の例として、Aura コンポーネントの属性の参照があります。

たとえば、PropertyPaginator Aura コンポーネントでは、基本的な式を使用して page、pages、total 属性の値を表示します。

<aura:component >
    <aura:attribute name="page" type="integer"/>
    <aura:attribute name="pages" type="integer"/>
    <aura:attribute name="total" type="integer"/>
    <div class="centered">{!v.total} properties • page {!v.page} of {!v.pages}</div>
</aura:component>

以下は、paginator Lightning Web コンポーネントの HTML ファイルの同等の構文です。

<template>
    {totalItemCount} items • page {currentPageNumber} of {totalPages}
</template>
メモ

メモ

Lightning Web コンポーネントの HTML ファイルの動的コンテンツには、感嘆符または値プロバイダ (v.) 構文がありません。入力し慣れているかもしれませんが、Lightning Web コンポーネントで Aura コンポーネントの式構文は使用しないでください。

HTML は paginator.js の totalItemCount プロパティを参照します。{currentPageNumber} および {totalPages} 式は、pageNumber および pageSize プロパティを処理する getter を参照します。

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    /** The number of items on a page. */
    @api pageSize;
    /** The total number of items in the list. */
    @api totalItemCount;
    get currentPageNumber() {
        return this.totalItemCount === 0 ? 0 : this.pageNumber;
    }
    get totalPages() {
        return Math.ceil(this.totalItemCount / this.pageSize);
    }
}

条件付きステートメントを理解したらすぐに、より複雑な式に取り組みます。

Aura の条件式は HTML の条件式になる

Aura コンポーネントの <aura:if> タグを、Lightning Web コンポーネントの HTML ファイルの if:true または if:false ディレクティブに移行します。

以下に、BrokerDetails Aura コンポーネントの条件付きマークアップを示します。

<aura:if isTrue="{!v.property.Broker__c}">
    <lightning:recordForm recordId="{!v.property.Broker__c}"
      objectApiName="Broker__c"
      fields="{!v.brokerFields}" columns="2"/>
</aura:if>

以下は、brokerCard Lightning Web コンポーネントの同様の HTML です。

<template if:true={property.data}>
    <lightning-record-form object-api-name="Broker__c" 
      record-id={brokerId} fields={brokerFields} 
      columns="2">
    </lightning-record-form>
</template>
メモ

メモ

Lightning Web コンポーネントの HTML ファイルの動的コンテンツには、{brokerId} 参照を囲む引用符がありません。これは入力ミスではありません。

Lightning Web コンポーネントの HTML ファイルは <template> 標準 HTML タグで始まり、そのボディ内に他の <template> タグを含めることもできます。この例では、<template> タグ内のコンテンツは、if:true ディレクティブの結果に応じて条件付きで表示されます。

Aura の複合式は JavaScript ロジックになる

属性値の参照など、Aura の基本的な式は HTML 式になることを確認しました。Aura コンポーネントの Aura 複合式 (比較演算や 3 項演算子など) を Lightning Web コンポーネントの JavaScript getter に移行します。

PropertyPaginator Aura コンポーネントで {!v.page > 1} が使用されているこの例のように、Aura コンポーネントでは豊富な式がサポートされています。

<aura:if isTrue="{!v.page > 1}">
    <lightning:buttonIcon iconName="utility:left" variant="border" onclick="{!c.previousPage}"/>
</aura:if>

Aura の式言語では、マークアップにより多くのロジックを含めることができます。その欠点は、このロジックの単体テストを行うことが難しくなり、唯一 JavaScript で単体テストができるコードのサブセットは機能です。

Lightning Web コンポーネントでは、複合式を JavaScript に移行します。これでコードを単体テストできるようになり、コードがより安定し、開発者は満足します。また、JavaScript のフル機能を使用してロジックを記述できます。

以下は、paginator Lightning Web コンポーネントの同様の HTML です。

<template if:false={isFirstPage}>
    <lightning-button-icon icon-name="utility:chevronleft" onclick={previousHandler}></lightning-button-icon>
</template>

paginator.js の getter によって {isFirstPage} 条件が評価されます。次に例を示します。

import { LightningElement, api } from 'lwc';
export default class Paginator extends LightningElement {
    /** The current page number. */
    @api pageNumber;
    get isFirstPage() {
        return this.pageNumber === 1;
    }
}

Aura のイテレーションは HTML のイテレーションになる

Aura コンポーネントの <aura:iteration> タグを、Lightning Web コンポーネントの HTML ファイルの for:each ディレクティブに移行します。

以下は、PropertyTileList.cmp の Aura 構文です。

<aura:iteration items="{!v.properties}" var="property">
    <c:PropertyTile property="{#property}"/>
</aura:iteration>

以下は、propertyTileList Lightning Web コンポーネントの同様の HTML です。

<template for:each={properties.data.records} for:item="property">
    <c-property-tile property={property} key={property.Id} 
      onselected={handlePropertySelected}></c-property-tile>
</template>

Aura の初期化子はライフサイクルフックになる

Aura コンポーネントの init イベントハンドラを、Lightning Web コンポーンネントの connectedCallback() JavaScript メソッドに置き換えます。connectedCallback() ライフサイクルフックは、コンポーネントが DOM に挿入されたときに起動します。ライフサイクルフックは、コンポーネントのライフサイクルの各フェーズでコードを実行できるコールバックメソッドです。

Aura コンポーネントでは init イベント使用して、コンポーネント構築後、表示する前にコンポーネントを初期化します。

以下は、PropertyCarousel Aura コンポーネントの init イベントハンドラです。

<aura:handler name="init" value="{!this}" action="{!c.onInit}" />

Aura コンポーネントのコントローラの onInit 関数で、必要な初期化が実行されます。

Lightning Web コンポーネントでは、コンポーネントの JavaScript ファイルの代わりに connectedCallback() を使用します。以下に、propertySummary.js の例を示します。

export default class PropertySummary extends LightningElement {
    ...
    connectedCallback() {
        // initialize component
    }
}

基本コンポーネントの移行

Lightning Web コンポーネントに Aura コンポーネントを含めることはできません。では、移行する必要がある Aura コンポーネントに Salesforce が提供する組み込みコンポーネントが含まれている場合は、どうしたらよいのでしょうか。Lightning 基本コンポーネントは Salesforce が lightning 名前空間で提供するビルディングブロックであり、Aura コンポーネントと Lightning Web コンポーネントの両方で使用できます。Lightning 基本コンポーネントを 2 つのプログラミングモデルで使用する場合、それぞれの構文は異なります。

この Aura コンポーネントでは、lightning:formattedNumber 基本コンポーネントが使用されています。

<aura:component>
    <lightning:formattedNumber value="5000" style="currency"
      currencyCode="USD" />
</aura:component>

このマークアップを Lightning Web コンポーネントに移行する方法は、次のとおりです。

  • 名前空間 (lightning) とコンポーネント名 (formattedNumber) を区切るコロンをダッシュに変更します。
  • キャメルケースのコンポーネント名 (formattedNumber) をダッシュで区切った名前 (formatted-number) に変更します。
  • キャメルケースの属性名 (currencyCode) をダッシュで区切った名前 (currency-code) に変更します。

以下は、同等の Lightning Web コンポーネントです。

<template>
    <lightning-formatted-number value="5000" style="currency"
      currency-code="USD">
    </lightning-formatted-number>
</template>
メモ

メモ

HTML 仕様では、カスタム要素のタグは自己終了でないことが規定されています。自己終了タグは /> で終わります。Lightning Web コンポーネントは、基本的にはカスタム要素です。したがって、<lightning-formatted-number> コンポーネントの参照には </lightning-formatted-number> という別個の終了タグが含まれます。この要件は、自己終了タグが許されている Aura コンポーネントとは異なります。

Aura の CSS は標準 CSS になる

Lightning Web コンポーネントでは標準の CSS 構文が使用されます。Aura コンポーネントのみで使用される THIS クラスを削除します。

以下は、PropertyTile Aura コンポーネントの CSS ファイルの一部です。

.THIS .lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}
.THIS .lower-third > p {
    padding: 0;
    margin: 0;
}
.THIS .truncate {
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

propertyTile Lightning Web コンポーネントの同様の CSS では、標準の CSS が代わりに使用されます。THIS キーワードは Aura 固有のもので、Lightning Web コンポーネントでは使用されません。

.lower-third {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    color: #FFF;
    background-color: rgba(0, 0, 0, .3);
    padding: 6px 8px;
}
.lower-third > p {
    padding: 0;
    margin: 0;
}
.truncate {
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Lightning Design System を使用してコンポーネントのスタイルを設定する

Lightning Experience または Salesforce モバイルアプリケーションに存在するカスタムコンポーネントアプリケーションでは、import ステートメントや静的リソースなしで Lightning Design System を使用することができます。Lightning Design System の CSS クラスを HTML 要素に割り当てれば完了です。

Lightning Web コンポーネントは Aura コンポーネントのスタイル設定を継承する

Aura コンポーネントのスタイルは、含まれている Lightning Web コンポーネントに伝播します。

ただし、Lightning Web コンポーネントのスタイルが、他の Lightning Web コンポーネントや Aura コンポーネントに干渉することはありません。読み間違いではありません。Lightning Web コンポーネントのスタイルは子に伝播しません。多くの問題を引き起こす可能性があるので、自分が所有しないスタイルの上書きは Lightning Web コンポーネントでは許可されていません。

Shadow DOM を使用した CSS のカプセル化

Lightning Web コンポーネントでは、コンポーネントを含むページからコンポーネント内部の要素を非表示にする、shadow DOM と呼ばれる Web 標準メカニズムが使用されています。Lightning Web コンポーンネントには shadow DOM があるので、コンポーネントのスタイルシートで定義されたスタイルはコンポーネントに範囲設定されます。これらのスタイルは、親、子、または兄弟コンポーネントには適用されません。このルールは厳格ですが、スタイルを失わずに異なるコンテキストでコンポーネントを再利用することができます。また、ページの他の部分のスタイルがコンポーネントのスタイルによって上書きされるのを防ぎます。

コンポーネント作成者が容易に開発できるようにするために、Lightning Web コンポーネントの shadow DOM は Web 標準とは少し異なる動作をします。その違いの 1 つは、Lightning Web コンポーネントの shadow DOM が自動的に作成されることです。コンポーネント作成者が実装する必要はありません。また、Lightning Web コンポーネントの shadow DOM は、shadow DOM をネイティブでサポートしないブラウザでも機能します。

リソース

無料で学習を続けましょう!
続けるにはアカウントにサインアップしてください。
サインアップすると次のような機能が利用できるようになります。
  • 各自のキャリア目標に合わせてパーソナライズされたおすすめが表示される
  • ハンズオン Challenge やテストでスキルを練習できる
  • 進捗状況を追跡して上司と共有できる
  • メンターやキャリアチャンスと繋がることができる