初心者から見たVue3コンポーネントの実装のしやすさについて Vision.4

# Vue3コンポーネントの実装のしやすさについて Vision.4

Vue3のコンポーネントの実装について、前回はVue3コンポーネントの概略から、
スロットを使ったコンテンツ配信と動的コンポーネントについて、
引き続きシンプルな実装を体験しました。

前回：スロットを使ったコンテンツ配信と動的コンポーネントについて

https://qiita.com/babel_0101/items/7eec3d164096ed09014c

今回は、DOM 内テンプレート解析の注意点を以下にまとめます。
なお、ここまでVueに触れてきて、そもそもDOMが何か分からない・知らない・忘れた<br>という場合には一度、ここで立ち止まってMDN（Mozilla Developer Network）の資料等<br>Javascriptの基本を振り返ってみましょう。

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction

## Vue3のコンポーネントの基礎4

公式ページ：[コンポーネントの基礎](https://ja.vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats)を読み進めながら、以下のように解釈。

**DOM内テンプレート解析の注意点(in-DOM Template Parsing Caveats):** 
VueのテンプレートをDOMに直接記述する際の注意点が書かれていました。<br>特に解釈の余地の無い注意点でしたので、素直に受け取りました。<br>公式ページの記載から、直訳的な表現を改めて紹介すると以下の通りになります。

::: note info
TIP
制限事項：本注意点はDOMに直接テンプレートを記述する場合にのみ適用。<br>以下のソースからの、文字列テンプレートを使用する場合は適用されない
・単一ファイルコンポーネント
・インラインのテンプレート文字列（例: template: '...'）
・`<script type="text/x-template">`
:::

1. **大文字小文字の区別**
HTMLタグや属性名は大文字と小文字を区別しません。<br>そのため、ブラウザはどの大文字も小文字として解釈します。
つまり、DOM内テンプレートを使用する場合<br>パスカルケースのコンポーネント名、キャメルケースの`props`名、`v-on`イベント名は<br>すべて<br>**ケバブケース（小文字ハイフン区切り）**<br>を使用しなければいけません。
   ```javascript:BlogPost.vue（javascript）
    // JavaScript 内ではキャメルケース
    const BlogPost = {
      props: ['postTitle'],
      emits: ['updatePost'],
      template: `
        <h3>{{ postTitle }}</h3>
      `
    }
   ```
   ```html:BlogPost.vue（html）
    <!-- HTML 内ではケバブケース -->
    <blog-post post-title="hello!" @update-post="onUpdatePost"></blog-post>
   ```
   上記例では、`postTitle`というプロパティはHTML上<br>`post-title`という属性で指定する必要があるということですね。
1. **自己クロージングタグ**
   自己クロージング（self-closing）タグについて
   ```vuejs:
    <MyComponent />
   ```
   上記のような記載は、DOM内テンプレートでは必ず明示的なクロージングタグを入れる必要があります。ケバブケースである点にも注意。
   ```vuejs:
    <my-component></my-component>
   ```
    これは[HTML仕様](https://html.spec.whatwg.org/multipage/syntax.html#void-elements)において、自己クロージングタグの省略が認められているタグが一部タグに限られているからです。最も一般的なのは`<input>` と`<img>`です。<br>HTML仕様で自己クロージングタグの省略が認められていないタグについて省略すると<br>単にHTMLタグが閉じられてないとブラウザに判断されるためです。
   以下のように書くと
   ```vuejs:
    <my-component /> <!-- ここがクロージングタグのつもりで書いても -->
    <span>hello</span>
   ```
   ブラウザは以下のように変換して解釈します。
   ```vuejs:
    <my-component>
      <span>hello</span>
    </my-component> <!-- ブラウザはここでクローズするよう解釈します -->
   ```
   自己クロージングタグの省略をせずに
   ```vuejs:
    <my-component></my-component>
    <span>hello</span>
   ```
   と記載しましょう。
1. **要素の配置制限**
リストやテーブル要素について、タグ内部に実装できるHTMLタグの配置に制限があります。<br>`<ul>`,`<ol>`,`<table>`,`<select>`等が対象となります。
内部に配置できる要素として例えば`<tr>``<td>`というタグは`<table>`の中で使用する<br>要素になります。
   ```html:
    <!-- ある表をHTMLで表現 -->
    <table>
      <thead>
        <tr>
          <th scope="col">Person</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th scope="row">Chris</th>
          <td>HTML tables</td>
          <td>22</td>
        </tr>
    </table>
   ```
このようなタグの配置制限がある中で、vueのコンポーネントを使用すると<br>問題が発生します。
   ```vuejs:
    <table>
      <blog-post-row></blog-post-row>
    </table>
   ```
カスタムコンポーネントとして記述した`<blog-post-row></blog-post-row>`部分が<br>画面描画時に、エラーとなる要素です。`tr`タグに特別な`is`属性を使用することで<br>エラーに対応できます。
   ```vuejs:
    <table>
      <tr is="vue:blog-post-row"></tr>
    </table>
   ```
::: note info
TIP
ネイティブのHTML要素で使用する場合、Vueコンポーネントとして解釈されるためには、`is`属性中で値を記述する前に`vue:`という固定文字列を付けます。<br>これはネイティブの組み込みのカスタマイズ要素との混同を避けるためです。
:::

以上が注意点でした。ここまででDOM要素に直接、Vueテンプレートを埋め込んで<br>いないので、実例があれば、また実装して試そうかと思います。<br>ひとまず今回は情報のインプットのみで留めます。

次回：グローバル登録について

https://qiita.com/babel_0101/items/a643cc19a13cede09ee2