はじめてのLightning Web Component 

## はじめに
この記事は、元Web屋で現SalesforceAdminの私が、HTML・CSS・JSあたりの知識をたよりにLWCを構築してみたログです。

▶今回使用したスキル：HTML,CSS,JS(クライアントサイド),SQLちょっと

## なにはともあれVScodeインストール
VSCode以外の開発環境しかインストールしてない人はVSCodeをインストールしましょう。LWCの開発環境を整えるためのステップはざっくり4つ。

1. VSCodeをダウンロード＆インストール
2. VSCodeにSF開発用アドオンをインストール
3. プロジェクト作る
4. 組織に接続

詳しくは↓のあたりで神々が解説してくださっていますので参考にしてください。餅は餅屋なので、この辺は本職の方々におまかせして解説すっ飛ばします。
[テラスカイ 高橋さんの記事](https://base.terrasky.co.jp/articles/5f2tk)
[アクセンチュア 小坂さんの記事](https://qiita.com/shunkosa/items/e6248520bff90f397158)

ちなみに私は、アドオンインストールの際、自分のマシンにインストールしてるJavaのエディションと必要なエディションが異なることに気づかないまま長い年月を消費するという雑魚な失敗をしています。これを読んでいる方は気をつけてね。

## 仕様を把握するためにレシピをインストールしてみよう
さて、ここで先人が作りし偉大なLWCレシピをご紹介します。
この中を覗けばLWCの仕様はざっくり把握できると思われます。
[日本語版のレシピはこちら](https://github.com/trailheadapps-jp/lwc-recipes-jp)

「レシピのインストール方法がわからん！」という方は、Trailblazer Communityにログインして以下のファイル13ページ目をチェックしてください。
我々の偉大な先人はそこまでフォローしてくださっています。足を向けては寝られませんね。
https://success.salesforce.com/0693A000007Hu8BQAS

###おすすめTrailhead
私は最初に[熊追跡のTrailheadプロジェクト](https://trailhead.salesforce.com/ja/content/learn/projects/lwc-build-flexible-apps)もご紹介いただいて作ってみました。
こちらもかわいくて愉快なのでおすすめです。


##新規コンポーネントを作ってみよう
ついでに私が作成したコンポーネントを晒しておきます。
今回のテーマで作ったLWCは、**商談に紐付いているTodoを条件つきで抽出して内容を表示するコンポーネント**です。

###新規LWCファイルを作成
VSCodeでローカルのプロジェクトフォルダを開き、エクスプローラウインドウでローカルのディレクトリ構造を確認します。
LWCディレクトリの上で右クリックをして表示されるメニューから「SFDX: Create Lightning Web Component」を選んでクリックし、コンポーネント名と作成するディレクトリを指定します（基本的にディレクトリはLWCのままでおｋ）。
<img width="433" alt="create_lightning_web_component.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244521/9aaadbda-001a-30b0-cc4d-dcfd46b06018.png">

すると、↓のような構造で、プロジェクト内に必要ファイルが勝手に生成されます。生成されたファイルは★マークで表現しました。

```
project/
  └ force-app/
    └ main/
      └ default/
        └ lwc/
          └ component-name/
            ├★component-name.html
            ├★component-name.js
            └★component-name.js-meta.xml
```

###Classを追加
今回はDBからTodoレコードを取得するので、レコード取得用のclassを作成します。
さきほどLWCのファイルを生成したのと同様に、classesディレクトリで右クリック、「SFDX: Create Apex Class」をクリックしてclassesディレクトリの中に　component-name.cls と component-name.cls-meta.xml を作成します。
ついでに先程生成されたコンポーネント名ディレクトリの中に新規ファイルとして component-name.cssを作っておきます。★のついたファイルが全部できてたらOK。

```
force-app/
└ main/
  └ default/
   ├ classes/
   │  ├★component-name.cls
   │  └★component-name.cls-meta.xml
   └ lwc/
      └component-name/
        ├★component-name.css
        ├★component-name.html
        ├★component-name.js
        └★component-name.js-meta.xml
```

###各ファイルをざっくり解説
**component-name.html**
表示レイアウト用のファイル。bodyタグの中身だけ引っこ抜いたような感じ。

**component-name.css**
このファイルにCSSを記述すると、html側に勝手に反映される。
ちなみにLWCは [Lightning Design System](https://www.lightningdesignsystem.com/) っていうCSSフレームワークが使えるので、これを利用すると時短になってハッピー。

**component-name.js**
クラスに変数を渡したり、DBから引っ張ってきたデータをこねこねするためのJSファイル。htmlファイルには余計なものを記述せずにJSはここに書く。

**component-name.js-meta.xml**
LWCの設定ファイル。

**component-name.cls**
DBとお話するためのファイル。
Salesforceからデータ引っ張るときには必要。

**component-name.cls-meta.xml**
clsの設定ファイル。


###実際のソース
以下、実際に作ったファイルの中身です。
処理が雑で不満なんだけど、とりあえず動いたぞ…。テストクラスの記載は省略。

####html

```
<template>
	<template if:true={data}>
		<lightning-card title="コンポーネントの見出し">
			<template for:each={data} for:item="task">
				<div key={task.Id}>
					<p class="slds-p-horizontal_small longtext">{task.Description}</p>
				</div>
			</template>
		</lightning-card>
	</template>
</template>
```

####js
データ取れてたら吐く、おわり。エラーはすっ飛ばした（真似してはいけない例）。

```
import { LightningElement, wire, track, api } from 'lwc';
import getTasks from '@salesforce/apex/documentStatus.getTasks';
export default class documentStatus extends LightningElement {
	@api recordId;
	@track data;
	@track error;
	@wire(getTasks, {OppId: '$recordId' , Title: '抽出したい文字列'})
        docData({ error, data}){
            if (error) {
            } else if (data) {
                this.data = data;
            }
        }
}
```

####js-meta.xml
今回は「レコードページでだけ使うよ」と指定しました。

```
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="DocumentSettings">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>documentStatus</masterLabel>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>
```

####css
ロングテキストエリアはそのまま表示させると長文で読みづらいので改行を再現します。

```
.longtext{
    white-space: pre-wrap;
}
```

####cls
SQL触ったことがあれば、データの取得自体はそんな大変じゃないと思います。
気をつけることは1にも2にもガバナ制限。 データ取ってくる回数は少ないほうがよいらしい。
あとは親子参照するときに癖があるからちょっと注意。
細かい仕様は公式のApexリファレンス、SOQLリファレンスを参照のこと。

```
public with sharing class documentStatus {
	@AuraEnabled(cacheable=true)
	public static List<Task> getTasks(Id OppId, String Title){
		List<Task> tasks = [SELECT id, Subject, Status, Description FROM Task WHERE WhatId = :OppId AND Subject = :Title ORDER BY CreatedDate DESC];
		if(tasks.isEmpty()){
			return null; //データが空の時の挙動が不審だったので、いっそ全部nullにしてやった。よくない例。
		}
		return tasks;
	}
}
```

####cls-meta.xml
APIのバージョンとか指定するやつ。

```
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>46.0</apiVersion>
    <status>Active</status>
</ApexClass>
```

##まとめ
ということで、興味はあれどしばらく敬遠していたLWCでしたが、意外とフロントエンドの知識が参考になるところがあったよーという記事でした。
まだコードの中身ががばがばなので、来年以降精進していくぞー。おー。