Help us understand the problem. What is going on with this article?

Vue.jsの <template>タグには複数の役割がある

先に結論書いてしまいますと、全部公式ドキュメントに書いてあります。

でも、書いてある箇所がバラバラなので
先に公式ドキュメントをちゃんと目を通していれば混乱しないのでしょうが、
ちゃんと読まずにいきなり現場のソースコード読んで、まぁどうにかなんだろうと思ったら
ん?この <template><template> はなんか違うの?? と混乱してしまった人(私です)向けにまとめました。

<template> タグには以下の役割があります。

  • 条件付きレンダリングで複数要素を対象とする場合(v-if)
  • リストレンダリングで複数要素を対象とする場合(v-for)
  • 名前付きスロット(v-slot)
  • 単一ファイルコンポーネント

条件付きレンダリングで複数要素を対象とする場合(v-if)

公式ドキュメントはこちら
https://jp.vuejs.org/v2/guide/conditional.html#%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%A7%E3%81%AE-v-if-%E3%81%AB%E3%82%88%E3%82%8B%E6%9D%A1%E4%BB%B6%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97

公式サイトにある例を引用:

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

v-if 属性を持った <template> タグは、 条件付きレンダリングです。

上の例でいうと、oktrue と評価される場合、以下のようにレンダリングされます。

  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>

<template> タグ自体はレンダリングされません。

リストレンダリングで複数要素を対象とする場合(v-for)

公式ドキュメントはこちら
https://jp.vuejs.org/v2/guide/list.html#lt-template-gt-%E3%81%A7%E3%81%AE-v-for

公式サイトにある例を引用:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

v-for 属性を持った<template> タグは、 リストレンダリングです。

上の例でいうと、例えば items[{msg: "foo"},{msg: "bar"},{msg: "baz"}] なら
以下のようにレンダリングされます。

<ul>
    <li>foo</li>
    <li class="divider" role="presentation"></li>
    <li>bar</li>
    <li class="divider" role="presentation"></li>
    <li>baz</li>
    <li class="divider" role="presentation"></li>
</ul>

<template> タグ自体はレンダリングされません。

名前付きスロット(v-slot)

公式ドキュメントはこちら
https://jp.vuejs.org/v2/guide/components-slots.html#%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%8D%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88

こちらはまず「コンポーネント」の理解から始めないといけないのですが
その説明をしだすと長くなるので、公式ドキュメントをみていただくとして、雑に説明すると

「コンポーネント」は、Vueの要素を部品化したもので
「スロット」は、コンポーネントを利用する際に、コンポーネントを呼び出す側からデータ等を渡すことができるのですが、それをはめ込む要素
のことです。

公式サイトの例を一部修正して引用 1

base-layout というコンポーネントが、以下のような構成だったとして。

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot name="main"></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

base-layoutを呼び出す側で、スロットに入れたい内容を、 v-slot 属性を指定した <template> タグで指定します。

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

実際のレンダリングは以下の通り:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

単一ファイルコンポーネント

公式ドキュメントはこちら
https://jp.vuejs.org/v2/guide/single-file-components.html

中規模以上のアプリケーションを実装していく場合
コンポーネントをそれぞれのファイル(.vueファイル)に分割し
webpack等でビルドする…という流れになります。

この時、コンポーネント化された.vueファイルで
HTML部、JavaScript部、CSS部を分離したとき、
HTML部のルート要素として <template> タグ を指定します。

公式ドキュメントより引用

<template>
  <p>{{ greeting }} World!</p>
</template>

<script>
module.exports = { 
  data: function () { 
    return { 
      greeting: 'Hello' 
    } 
  } 
} 
</script> 

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

  1. デフォルトスロットの説明がまた面倒なので、デフォルトスロットを使わない説明に変えています。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away