Salesforce Auraコンポーネントの基礎の基礎

# これは何？
この記事は「[24日後に立派なSalesforceエンジニアになるWEBエンジニア Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kakakaori)」の18日目の記事です。7日後に立派なSalesforceエンジニアになるために今日からはAuraコンポーネントについて学んでいきたいと思います。

# Auraコンポーネントとは？
Auraコンポーネントは、先日記事に書いた[Visualforce](https://qiita.com/kakakaori830/private/413bb9e4e78ff12d9741)よりも後に出てきたプログラミングモデル。さらにその後出てきたのが[Lightning Web Component](https://qiita.com/kakakaori830/items/04e1e734dc894478c5a3)である。
>Lightning Web コンポーネントは Aura コンポーネントよりもパフォーマンスが高く、開発も容易です。ただし、LWC のサポート範囲はまだ Aura よりも狭いため、Lightning Web コンポーネントの開発では Aura が必要になる場合もあります。
[Lightning Web Components または Aura の選択方法](https://developer.salesforce.com/docs/component-library/documentation/ja-jp/lwc/lwc.get_started_lwc_or_aura)

に記載がある通り基本的にはLWCで実装することを公式としても推奨しているのだが、Auraじゃないとできないこともあるので、~~仕方がなく~~学んでおこうと思う。
ちなみにAuraコンポーネントの中からLWCを呼び出すことはできるが、LWCの中からAuraコンポーネントを呼び出すことはできない。

# ファイル構成
新規でAuraコンポーネントを作成すると以下のようなファイルが生成される。ファイル数が多いし、ぱっと見て、どのファイルが何をするのか想像しづらいので一つずつ見ていく。
```
aura
 └ test
    ├ test.auradoc
    ├ test.cmp
    ├ test.cmp-meta.xml
    ├ test.css
    ├ test.design
    ├ test.svg
    ├ testController.js
    ├ testHelper.js
    └ testRender.js
```

## auradoc
auradocを使って仕様書を作成することができる。
詳細については[こちら](https://developer.salesforce.com/docs/atlas.ja-jp.lightning.meta/lightning/components_documentation.htm)に詳しくのっているが、今回は実際のプログラミング箇所を中心としてみていくため割愛。

## cmp
Auraコンポーネントを作る際の必須ファイル。中身はhtmlぽい書き方だが、コントローラーなど外部ファイルの読み込みを行ったり、変数の宣言をしたり、見た目（UI）の定義だけではない様々な処理を行う。サンプルコードを見た方が伝わりやすいと思う。

```html:test.cmp
<aura:component
  implements="flexipage:availableForAllPageTypes"
  access="global"
  controller="SampleController"
>
  <aura:handler name="init" value="{!this}" action="{!c.initEvent}" />
  <aura:attribute name="id" type="String" />
  <aura:attribute name="disable" type="Boolean" default="true" />
  <lightning:workspaceAPI aura:id="workspace" />

  <lightning:button
    variant="Neutral"
    label="OpenTab"
    onclick="{! c.handlerClick }"
    disabled="{! v.disable }"
  />
</aura:component>
```

ちょっとずつ解説していく。

### aura:component implements
まず`implements="flexipage:availableForAllPageTypes"`これはインターフェースをコンポーネントに追加するための処理。AuraコンポーネントをLightningアプリケーションビルダーやLightningページに表示するためには、必ずインターフェースを指定する必要があり、どこでAuraコンポーネントを呼び出した以下によって指定する内容が異なる。
| インターフェース |  |
|:-|:-|
| flexipage:availableForRecordHome	  | レコードページ専用に設計されている場合  |
| flexipage:availableForAllPageTypes  | レコードページだけではなく他のページでも使える場合  |
| clients:availableForMailAppAppPage  | Lightningアプリケーションビルダー、Lightningページ、メールアプリケーションでで使える場合  |

またそのコンポーネントでレコードIDをとってくる必要があるときは `implements="flexipage:availableForAllPageTypes,force:hasRecordId"`のように`force:hasRecordId`も追加する。

同様にコンポーネントでオブジェクト名をとってくる必要がある時は`force:hasSObjectName`を追加する。

### aura:component access
これを`access="global"`にしているとコンポーネントを自分の組織外で使用できるようになるため、コンポーネントを配布する際はglobalにしておく。

### aura:component controller
コンポーネントのApexコントローラーの指定を行う。Visualforceの時と一緒。

### aura:handler 
`aura:handler`を使うことでコンポーネントにイベント処理を実装することができる。以下の例では`init`イベントを使うことで、コンポーネント初期化時にコントローラーに記載した`initEvent`を呼び出す。

```html:test.cmp
<aura:component>
  <aura:handler name="init" value="{!this}" action="{!c.initEvent}" />
</aura:component>
```

```javascript:testController.js
({
    initEvent: function(cmp) {
      alert('init ok!');
    }
})
```

よく使うイベントは下記の3つ。
#### [init](https://developer.salesforce.com/docs/atlas.ja-jp.lightning.meta/lightning/js_cb_init_handler.htm)
コンポーネントの初期化時にイベントが発生する。
```html:
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
```
#### [change](https://developer.salesforce.com/docs/atlas.ja-jp.lightning.meta/lightning/js_cb_data_change.htm)
valueに設定された値を監視して、それが変更された時にイベントが発生する。
```html:
<aura:handler name="change" value="{!v.numItems}" action="{!c.itemsChange}"/>
```
#### [render](https://developer.salesforce.com/docs/atlas.ja-jp.lightning.meta/lightning/js_render_handler.htm)
コンポーネントのレンダリング時にイベントが発生する。
```html:
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
```

### aura:attribute
コンポーネントで扱う変数を定義する。設定できる内容は以下の通り。

|  | 説明 |
|:-|:-|
| access  |  `public`、`global`、`private`を指定できる。デフォルトは`public`。 |
| name  | 変数名にあたるもの。必須項目。  |
| type  |  型を定義。必須項目。 |
|  default | デフォルト値。  |
| required  | 必須かどうかを設定。デフォルトはfalse。  |
|  description | 変数の用途の概要を記載する。  |

## cmp-meta.xml
今のところ特に触ったことがない。

## test.css
コンポーネントに適応するスタイルを指定する。
[デザイントークン](https://www.lightningdesignsystem.com/design-tokens/#category-text-color)が用意されているので、それを使うことで値をハードコーディングせずにレイアウトを作成することができる。

## test.design
コンポーネントのプロパティを設定することができる。
```html:
<design:component label="Aura testコンポーネント" >
    <design:attribute name="test" label="テストラベル" />
</design:component>
```

このように設定しておくと以下のようにコンポーネントの表示ラベルや、値渡しができる。
![スクリーンショット 2022-12-13 22.18.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/59f076d2-68ae-5699-c4cf-980407939af2.png)

## test.svg
コンポーネントのアイコンをsvgで指定できる。

## testController.js
イベントハンドラを定義して、`c.hogeHandler`のようにしてコンポーネントから呼び出すことができる。逆にコンポーネント以外からはコントローラーを呼び出すことはできない。
```html:test.cmp
<aura:handler name="init" value="{!this}" action="{!c.initEvent}" />
```

```javascript:testController
({
  initEvent: function (component, event, helper) {
     // 処理
  }
});
```
## testHelper.js
コントローラーの処理で関数として切り出したいものとかはヘルパーに記載する。慣習的に第１引数に`component`、第２引数に`helper`を渡し、それ以降で独自の引数を渡すことが多い。
```javascript:testController
({
  initEvent: function (component, event, helper) {
     helper.test(component, helper);
  }
});
```

```javascript:testHelper
({
  test: function (component, helper) {
    // 処理
  }
});
```
## testRender.js
以下の4つのタイミングでの処理を定義することができる。またRender.js内からはController.jsと同様にHelper.jsを呼び出すことができる。
| 種類 | 説明 |
|:-|:-|
| render  |  画面が描画される直前に走る |
| rerender  |  再描画の完了時に走る |
|  afterRender | 初回描画の完了時に走る  |
|  unrender | コンポーネントが破棄された時に走る  |

```javascript:testController
({
  render: function (component, helper) {
     helper.test('foo');
  }
});
```

```javascript:testHelper
({
  test: function (testText) {
    // 処理
  }
});
```

# 最後に
少し長くなってしまいましたが、Auraコンポーネントの概要とファイル構成についてまとめました。正直Visualforce同様、あまり積極的に使っていきたくない思いはあるものの、LWCでまだ実装できない内容もあるので立派なSalesforceエンジニアになるためにはAuraも知っておく必要がありそうです。
明日はLWCで実装できないAura特有の処理の一つであるタブの制御について見ていきたいと思います。