LoginSignup
0
0

LWCのJS内でclassを用意できたので、ループ内で要素の関数が呼び出せるようになった

Last updated at Posted at 2024-02-22

はじめに

以前書いたときはJavaScriptのclassの仕組みをあんまり理解できていなかったため、とんちんかんなアプローチをしていました。
LWCのJS内でクラス(っぽいもの)を用意したい

今回ある程度学が身についたので「あれ、できるんじゃね?」と試したところあっさりできたので、ご報告も兼ねて完全版を残しておこうと思います。

やりたかったこと

画面に表示するデータを、同じデータ構造で複数種類保つ必要があったため、クラスに定義して保存するようにしたかった。

できたこと

コード

画面用のclassの外で利用したいclassを定義する。

testComponent.js
import { LightningElement } from 'lwc';

export default class TestComponent extends LightningElement {

	personList = [];

	connectedCallback() {
		this.personList.push(new person('テスト A'));
		this.personList.push(new person('テスト B'));
		this.personList.push(new person('テスト C'));
	}
}

class person {
	/**
	 * 名前
	 */
	name;
	/**
	 * 年齢
	 */
	age;
	/**
	 * 身長
	 */
	height;
	/**
	 * 体重
	 */
	weight;

	constructor(name) {
		this.name = name;
		this.age = this.getRandomInt(100);
		this.height = 120 + this.getRandomInt(80);
		this.weight = 30 + this.getRandomInt(100);
	}

	/**
	 * 自己紹介文
	 */
	get selfIntroduction() {
		return `私の名前は${this.name}。\r\n`
			+ `年齢は${this.age}歳だよ。`;
	}

	/**
	 * 乱数を生成する
	 */
	getRandomInt(max) {
		return Math.floor(Math.random() * max);
	}
}
testComponent.html
<template>
	<lightning-card icon-name="custom:custom27" title="テスト">
		<div class="slds-var-p-around_medium">

			<template for:each={personList} for:item="person">
				<div key={person.name} class="slds-box slds-var-p-around_small slds-var-m-bottom_small">
					<p>氏名:{person.name}</p>
					<p>年齢:{person.age}歳</p>
					<p>身長:{person.height}cm</p>
					<p>体重:{person.weight}kg</p>
					<div class="slds-box slds-theme_shade">{person.selfIntroduction}</div>
				</div>
			</template>

		</div>
	</lightning-card>
</template>

image.png

良い点

見るべきところを纏められる

他の言語でclassを作ったときと概ね同じ。

javadocがきちんと効く

以前書いたものだと、コードの記法次第でjavadocが効かないことがあったが、今回のものは完璧!
javadocがばっちり効きます。
image.png

要素ごとのgetterが定義できる → ループ内でそれぞれ動作させられる!

先程のコードサンプルにあったget selfIntroduction()をループ内で呼び出してる部分ですが、実は(個人的に)ちょっと画期的なことで・・。
LWCのループ内部で、要素ごとに関数を適用するのって一筋縄ではできないんですよね。

そんな悩みもclassを作ることで解決します。やったね。

apexから渡された値を、かなり手軽にclassに変換できるっぽい

const personObject = {
    name: 'テストA'
    ,age: 19
    ,height: 170
    ,weight: 60
    ,unnecessaryProperty: 'abc'
};
const personClass = Object.assign(new person(), personObject));

これだけでclassに変換できました。
余計なプロパティunnecessaryProperty はエラーなどが出たりはせず、保持したままとなっていました。

悪い点

未定義プロパティに値を設定できる

誤字や作ったつもりで、未定義のプロパティを参照したとき、なんの問題もなく処理が進んでしまいました。

classはuse strictが適用されているはずなんだけど・・なんでだ・・?
厳格モード - JavaScript | MDN

誤字に気をつけるしかない!というのがちょっと気持ち悪いところではあります。

privateが使えない

これはLWC側の規約ですが・・。
privateメソッドやプロパティが使えないようです。

実際に定義してデプロイすると、下記のエラーが発生します。
LWC1535: Unexpected plugin compilation error: Plugin - lwc, Hook - transform, Cause - SyntaxError: LWC1007: /home/sfdc/tools/lwc/248.10.2-5.0.8/testComponent.js: Class private methods are not enabled. Please add '@babel/plugin-transform-private-methods' to your configuration.

まあ使いたいシーンがあるかと言われると微妙なので、そこまで支障ないとは思いますが・・。
ちょっと残念。

以前と比べて良くなったところ

そもそも、無理やり作ったclassっぽいものではなく、きちんと仕様に則ってclassを作っているというだけでかなりこう、気持ちが違います。

あとは、関数を用意したい場合に別途getterの定義をしなくて良くなったのが大きいですね。
使い勝手の向上って感じだ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0