Component指向に辿りつくための設計について考えてみる

# Component設計とはどうあるべきだろうか?
Componentという考え方を導入して、アプリケーションを作成することを考えてみましょう
まずComponentがどういったものであるべきか、というのを考えてみます

- Componentの集合は最終的に文書となる
- 一つのComponentは一つの概念であり、データの単位である
- Componentは1つ以上のComponentから構築される

# まずは文書であるということを考えよう
古来Webがどうであったかについて立ち戻りましょう

OLDな時代の(1990年代以前とかの)WebというのはHTMLのことであり、タグというメタ情報をつけられていた構造的なドキュメントです
それは「構造化された文書(や他のデータ)の集合」です
この概念を踏まえてHTML tagというものが定義され、構造化された文書というものが記述されます。
この構造化された文書であるということがHTMLであることの最大の特徴であるのでこれを覚えておいてください


# 文書とは構造化されたComponent群であると考える
## 最もSimpleな文書の構造はtag
HTMLにおいての構造において最小の単位はtagです。このTagをComponentはとしてしまう例をあげてみます
```vue
<script setup lang="ts">
intercae Props {
  value: string;
}
const props = withDefault(defineProps<Props>(), {value: ''})
</scriot>

<template>
<p>{{ value }}</p>
</template>
```
このようなComponentをつくってしまうことは可能です
しかし、これはあまりに面倒ですし、利便性にも欠けるので作成すべきではないでしょう
ただ、tagをComponentであると見做して、Component設計をしていくという方法はあってもよいと考えます

## 一つの意味をもつデータの単位→Component
単一のtagが一つの意味をもつのであれば、それを一つのComponentと見做すことはできます
しかし現実の世界やデザインは単独の要素や単独のtagで表現できるとは限りません
例えば人物というのを考えてみましょう
人物は名前を持ち、画像を持ち、肩書を持ち、概要を持つとページではされるかもしれません。そうなったらそれは立派に一つのComponentとしてデザインされるべきでしょう
```vue
<script setup lang="ts">
interface Person {
name: string;
imgSrc: string;
position: string;
text: string;
}
interface Props {
  person: Person;
}

const props = defineProps<Props>()
</script>

<template>
<div class="person">
  <img :src="props.person.imgSrc"/>
  <div class="name">{{ props.person.name }}</div>
  <div class="position">{{props.person.position}}</div>
  <div class="body">
    <p>{{ props.person.text }} </p>
  </div>
</div>
</template>
```
このような「人物」のようなものは文書の内部でもtagとして構成されるのではなくPersonとでも名前がつけられたComponentによって構成されるべきです
このように一つの概念をComponentとして定義し、それらを文書の内部に設置することによってtagで書かれるより抽象度の高い概念によって表現できます

```vue
...
<tempalte>
  <h1>商品一覧</h1>
  <div class="items">
    <Item v-for="item in items" :key="item.id" :item="item"/>
  <div>

 <h1>参加者一覧</h1>
 <div class="persons">
   <Person v-for="person in persons" :key="person.name" :person="person"/>
 </div>
</template>

```
v-forで繰り返す部分を通常のHTML tagとして記述してもよいのですが、Componentで記述することですっきりしたというだけでなく「ここは商品がならぶのだな」とか「ここは人物の情報が掲載されるのだな」ということが理解しやすくなります

## Componentを構成する基準をどう考えるか
一つのまとまったデータの単位、ではあるのですが、これがよくわからないのであれば
「一つの名詞として(文書内で)抽象化できるもの」を基準にすればよいでしょう
人物、商品、絵画、旅行先、サマリー、、など、その文書内の一定のまとまりを一つの名詞として呼ぶことができるのであれば、それはComponentとするべき重要な指標となります

## Section
文書の中には機能的な意味の集合のようなもの、まとまりがあります
Sectionとでもよぶようなものですが、これもComponentとすべき候補です
SectionをComponentとしてまとめることによって、上位のComponentからみたときに文書の構造がどのようなものになっているのかが分かりますくなります

```vue
<template>
  <header/>
  <items />
  <recommends/>
  <comments/>
  <footer/>
</template>
```
上記のようにComponentがならべられていたとしたら、その文書がどういった構成でどういった並びであるのか一目で理解できるでしょう

## ちょっとした例外
文書の冒頭にある、ただのお言葉みたいなものをComponent化すべきか、という問題はあります
最初の例にもどるわけですが、そういった名付けるのが難しいが存在していて、単純なtagで表現が可能であるなら、それはそのままtagとして構成してしまった方がいいでしょう
それでおさまらない場合は文書の中で何か役割をあたえて、どのようにComponentとしていくか検討すべきです

# まとめ
tagの羅列によって並べられ文書に比べて、Componentによるデザインで記述されると、抽象度が高く構造的に見通しの良い文書が作成できます

そのために
- 1つのデータの形にたいして1つのComponentを作成する
- Componentの作成の目安として、名詞として呼びあらわせるかどうかを考える
- データを表現するComponentを組みあわせることで、構造的にわかりやすいComponentを作成する
- 文書を抽象的に構造化されたComponentを組みあわせて最終的に文書を作成する

Componentデザインによって一定の規律をあたえることで、文書が構造的に見易くなります
ComponentをよりPrimitiveなものと考えて文書を構成していくことが、Component指向の出発点となるのです