はじめに
Reactに慣れていて、Thymeleafでモーダルを共通化しようとしたら「モーダルの中身(content/children)が二重で表示される」現象でちょっと違うなと思いました。Thymeleafの特徴の後に、fragmentをpropsやchildrenみたいに渡して使うときの注意点をまとめます。
前提知識
HTMLをサーバーサイドで構築する。
「再利用」を利用するためにfragment
やblock
等を使う。
React のような動的UIとは違い、基本は静的HTMLとして出力されるため、扱いには注意する。
fragment
イメージ
再利用可能なHTML部品(≒ コンポーネント定義)
子コンポーネント
fragments/card.html
<div th:fragment="userCard(name)">
<div class="card">
<p th:text="${name}"></p>
</div>
</div>
親コンポーネント(呼び出し)
<div th:replace="fragments/card :: userCard(${user.name})"></div>
出力イメージ
<!-- <div th:fragment="userCard(name)"> の<div>は表示されない -->
<div class="card">
<p>田中</p>
</div>
複数propsもどきの扱い
子コンポーネント
fragments/card.html
<div th:fragment="userCard(name)">
<div class="card">
<p th:text="${name}"></p>
</div>
</div>
親コンポーネント
<div
th:replace="fragments/card :: userCard(
name=${user.name},
age=${user.age},
role='admin')"></div>
※下記でも可能だが、上記の方がわかりやすい。
<div th:replace="fragments/card :: userCard(${user.name}, ${user.age}, ${user.role})"></div>
insert
イメージ
呼び出し元のタグの中に、fragmentを子として表示する。
子コンポーネント
fragments/info.htm
<div th:fragment="infoBox">
<p>お知らせ:メンテナンス予定あり</p>
</div>
親コンポーネント
<section th:insert="fragments/info :: infoBox"></section>
出力イメージ
<section>
<div>
<p>お知らせ:メンテナンス予定あり</p>
</div>
</section>
下記のタグは残って、その中の子要素になる。
<section th:insert="fragments/info :: infoBox"></section>
--- 今日はここまで 近日中に追記する ---