tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:Lightning Web コンポーネント開発を試してみました

Lightning Web コンポーネント開発を試してみました。
f:id:tyoshikawa1106:20200119180059p:plain

仕事でSalesforceアプリを開発するときにはVisualforceページで開発しているのと、どうしてもLightningコンポーネント開発が必要になるときには一つ前のバージョンのLightning Auraコンポーネントで開発を行ったため、今の所必要になることもなかったのですが、Winter'20の認定資格更新モジュールをクリアするのに必要になってしまったので、重い腰を上げてやってみました。

Lightning Web コンポーネント開発の始め方

Lightning Web コンポーネント開発の始め方ですが、YoutubeのSalesforce Developers Japanのチャンネルで動画が公開されています。
f:id:tyoshikawa1106:20200119180402p:plain

Salesforce Developers Japan - YouTube


実際に作成するのはこの辺りからだと思います。
f:id:tyoshikawa1106:20200119181142p:plain

Lightning Web コンポーネントでHello Wolrd

1. SFDC:Create Lightning Web Componentコマンド実行

コマンド実行でファイルを作成します。
f:id:tyoshikawa1106:20200119181521p:plain

ファイル名はここで入力。
f:id:tyoshikawa1106:20200119181556p:plain


こんな感じでLWCファイルを作成できます。拡張子は.jsです。
f:id:tyoshikawa1106:20200119181721p:plain


作成されるファイルは下記の3つです。

  • helloLwc.js
  • helloLwc.html
  • helloLwc.js-meta.xml


ファイル名の先頭は小文字になるようです。自分の環境ではHelloLwc.jsで最初つくられたのですが保存してSalesforce側にデプロイしたタイミングか、それ以外のどこかで上記の3つのファイルにアクセスできるようになりました。


.xmlのファイルで使用箇所などの設定ができるみたいです。
f:id:tyoshikawa1106:20200119182727p:plain

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>47.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>


.htmlファイルでHTMLコードを記述します。
f:id:tyoshikawa1106:20200119182843p:plain

<template>
    <p>Hello LWC!</p>
</template>


DeployコマンドでSalesforce側にリリースします。
f:id:tyoshikawa1106:20200119182957p:plain


正常にリリースすると設定のLightningコンポーネントのページに追加されます。
f:id:tyoshikawa1106:20200119183129p:plain


ここまでできればLightningアプリケーションビルダーで利用可能になっていると思います。今回のコードの場合はホームのページで利用できるコンポーネントです。
f:id:tyoshikawa1106:20200119183331p:plain:w200


あとはドラッグ&ドロップで追加するだけ。テキストが表示されるシンプルなコンポーネントです。
f:id:tyoshikawa1106:20200119183434p:plain


背景も何も無い状態で表示されました。
f:id:tyoshikawa1106:20200119183543p:plain


上記まででLWCコンポーネントの最低限の枠ができました。続いてJS処理の実装です。「{name}」という感じに書くとバインド変数として扱われます。

<template>
    <p>Hello {name}!</p>
</template>

f:id:tyoshikawa1106:20200119195833p:plain


JS側はこんな感じ。

import { LightningElement } from 'lwc';

export default class HelloLwc extends LightningElement {
    name = 'Lightning';
}

f:id:tyoshikawa1106:20200119195926p:plain


デプロイコマンドでリリースするとSalesforce側に変数で宣言した値が表示されることを確認できます。
f:id:tyoshikawa1106:20200119200119p:plain


次はInputフィールドの使い方です。

<template>
    <p>Hello {name}!</p>
    <div>
        <input value={name} onkeyup={onNameChanged} />
    </div>
</template>


JSファイル側は次のように変更します。

import { LightningElement,track } from 'lwc';

export default class HelloLwc extends LightningElement {
    @track name = 'Lightning';

    onNameChanged() {
        this.name = this.template.querySelector('input').value;
    }
}

f:id:tyoshikawa1106:20200119200617p:plain


これでテキストボックスに入力した結果が画面に表示されるようになりました。
f:id:tyoshikawa1106:20200119200736p:plain


次はチェックボックスをつかった条件判定についてです。また、今回は複数のInputフィールドを用意するのでquerySelectorの条件をID指定にします。

<template>
    <p>Hello {name}!</p>
    <div>
        <input data-id="inputName" value={name} onkeyup={onNameChanged} />
    </div>
    <div>
        <input data-id="inputCheckbox" type="checkbox" onchange={onCheckboxChanged} />
        <template if:true={isChecked}>表示</template>
        <template if:false={isChecked}>非表示</template>
    </div>
</template>

f:id:tyoshikawa1106:20200119202447p:plain


JS側はこんな感じ。

import { LightningElement,track } from 'lwc';

export default class HelloLwc extends LightningElement {
    @track name = 'Lightning';
    @track isChecked = false;

    onNameChanged() {
        this.name = this.template.querySelector('[data-id="inputName"]').value;
    }

    onCheckboxChanged() {
        this.isChecked = this.template.querySelector('[data-id="inputCheckbox"]').checked;
    }
}

f:id:tyoshikawa1106:20200119202523p:plain


これで複数のInputフィールドのクエリセレクターの使い方とチェックボックスの値によるIF判定を動かすことができました。
f:id:tyoshikawa1106:20200119202632p:plain


最後にリスト表示についてです。今回は先にJSの処理から。

import { LightningElement,track } from 'lwc';

export default class HelloLwc extends LightningElement {
    @track name = 'Lightning';
    @track isChecked = false;
    @track members = [
        {
            id: "1",
            name: "Sato"
        },
        {
            id: "2",
            name: "Suzuki"
        },
        {
            id: "3",
            name: "Tanaka"
        }
    ];

    onNameChanged() {
        this.name = this.template.querySelector('[data-id="inputName"]').value;
    }

    onCheckboxChanged() {
        this.isChecked = this.template.querySelector('[data-id="inputCheckbox"]').checked;
    }
}


HTML側はこんな感じ。

<template>
    <p>Hello {name}!</p>
    <div>
        <input data-id="inputName" value={name} onkeyup={onNameChanged} />
    </div>
    <div>
        <input data-id="inputCheckbox" type="checkbox" onchange={onCheckboxChanged} />
        <template if:true={isChecked}>表示</template>
        <template if:false={isChecked}>非表示</template>
    </div>
    <div>
        <ul>
            <template for:each={members} for:item="member" for:index="index">
                <li key={member.id}>{index}. {member.name}</li>
            </template>
        </ul>
    </div>
</template>

f:id:tyoshikawa1106:20200119203455p:plain


これでリスト表示ができました。
f:id:tyoshikawa1106:20200119203519p:plain


リスト表示のもう一つの書き方です。

<template>
    <p>Hello {name}!</p>
    <div>
        <input data-id="inputName" value={name} onkeyup={onNameChanged} />
    </div>
    <div>
        <input data-id="inputCheckbox" type="checkbox" onchange={onCheckboxChanged} />
        <template if:true={isChecked}>表示</template>
        <template if:false={isChecked}>非表示</template>
    </div>
    <div>
        <!--
        <ul>
            <template for:each={members} for:item="member" for:index="index">
                <li key={member.id}>{index}. {member.name}</li>
            </template>
        </ul>
        -->
        <ul>
            <template iterator:it={members}>
                <li key={it.value.id}>{it.index}. {it.value.name}: {it.first} : {it.last}</li>
            </template>
        </ul>
    </div>
</template>

f:id:tyoshikawa1106:20200119204903p:plain


この書き方でもリスト表示ができました。また、リストの最初と最後の判定も動いています。
f:id:tyoshikawa1106:20200119204959p:plain


以上がSalesforce Developer JapanのYoutube動画で公開されているのを見ながら試してみたLightning Webコンポーネント開発の基本的な部分です。Apexコードとの連携は含まれていませんがこれをベースに勉強をしていけば良さそうでした。

おまけ

上記で覚えたやり方をベースにWinter'20でつくるハンズオンをやってみました。

HTML
<template>
    <lightning-card  title="Hello">
        <lightning-button label="New" slot="actions"></lightning-button>
        <p class="slds-p-horizontal_small">Card Body (custom component)</p>
        <p slot="footer">Footnote</p>
    </lightning-card>
    <lightning-button label="New" title="Non-primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
</template>
JS
import { LightningElement } from 'lwc';

export default class MyComponent extends LightningElement {}
XML
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>47.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>
カスタムタグ

f:id:tyoshikawa1106:20200119210217p:plain


これで完成。
f:id:tyoshikawa1106:20200119210343p:plain


Ligtning Webコンポーネントの基本的な使い方はこんな感じでした。
f:id:tyoshikawa1106:20200119210354p:plain

その他参考