← 解説「コンポーネント — UIの基本単位」に戻る
サンプルコードで身につける: コンポーネント — UIの基本単位
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1最小のコンポーネント
コンポーネントの最小構成は「selector(タグ名)」と「template(表示内容)」の2つだけです。クラスにデコレータを付けるとHTMLタグとして使える部品になる、という核の部分を示しています。どんなに複雑な画面部品も、出発点はこの形です。
import { Component } from '@angular/core';
// selector がHTMLタグ名、template が表示内容になる
@Component({
selector: 'app-hello',
template: '<p>はじめてのコンポーネント</p>',
})
export class HelloComponent {}
// 使う側のテンプレートに <app-hello /> と書くと、
// その場所に <p>はじめてのコンポーネント</p> が表示される
2複数の要素を持つテンプレート
templateには1つの要素だけでなく、HTMLのかたまりをそのまま書けます。「見出しと本文を持つカード」のように、意味のあるまとまりを1部品にするのがコンポーネント分割の基本です。実務のコンポーネントはほとんどがこうした複数要素のテンプレートを持ちます。
import { Component } from '@angular/core';
@Component({
selector: 'app-profile-card',
// テンプレートには複数の要素をまとめて書ける
template:
'<article>' +
' <h2>プロフィール</h2>' +
' <p>フロントエンドエンジニア。Angularを勉強中。</p>' +
'</article>',
})
export class ProfileCardComponent {}
3styles でこの部品だけの見た目を持つ
stylesに書いたCSSは、このコンポーネントの中だけに効きます。他の場所に同じクラス名があっても影響し合わない「スタイルのカプセル化」がコンポーネントの大きな利点です。実務では部品ごとに見た目のルールを閉じ込めることで、CSSの予期せぬ衝突を防ぎます。
import { Component } from '@angular/core';
@Component({
selector: 'app-notice',
template: '<p class="notice">本日23時からメンテナンスを行います</p>',
// styles はこのコンポーネントの中だけに効く
styles: ['.notice { color: darkorange; font-weight: bold; }'],
})
export class NoticeComponent {}
// 別のコンポーネントに .notice クラスがあっても影響しない
4コンポーネントを入れ子にする
あるコンポーネントの中で別のコンポーネントを使うには、使う側の imports に登録してテンプレートにタグを書きます。「部品の中に部品を置く」というこの入れ子構造こそが、Angularで画面を組み立てる基本の形です。
import { Component } from '@angular/core';
@Component({
selector: 'app-site-header',
template: '<header><h1>マイショップ</h1></header>',
})
export class SiteHeaderComponent {}
@Component({
selector: 'app-page',
// 使いたいコンポーネントを imports に登録してタグで呼び出す
imports: [SiteHeaderComponent],
template: '<app-site-header /><main>本文エリア</main>',
})
export class PageComponent {}
5画面を意味のある部品に分割する
実務のページは「ヘッダー」「商品一覧」「フッター」のように意味のある単位へ分割し、親コンポーネントで組み立てます。各部品が別ファイルに分かれることで、修正の影響範囲が部品の中に閉じ、同じヘッダーを別ページでも再利用できます。実際のプロジェクトのトップページは、ほぼ必ずこういう構造になっています。
import { Component } from '@angular/core';
import { HeaderComponent } from './header.component';
import { ProductListComponent } from './product-list.component';
import { FooterComponent } from './footer.component';
// 商品ページを「ヘッダー・一覧・フッター」の3部品で組み立てる
@Component({
selector: 'app-shop-page',
imports: [HeaderComponent, ProductListComponent, FooterComponent],
template:
'<app-header />' +
'<app-product-list />' +
'<app-footer />',
})
export class ShopPageComponent {}