元Webデザイナー兼コーダーの備忘録

ウェブデザインやプログラミング、ブログのカスタマイズなどについてアウトプットしています。

 メニュー

» HTML入門のまとめはこちらです。

【Vue.js】コンポーネントにデータを渡す:props

例えば、コンポーネントを使ってブログを作成するとなると、記事のタイトルや投稿内容などのデータをコンポーネントに渡して処理することになります。今回は、コンポーネントにデータを渡す方法について書きます。

カスタム属性としてデータを渡す

<!-- blog-postタグのtitle属性に値を指定 -->
<div id="app">
  <blog-post title="HTMLについて"></blog-post>
  <blog-post title="CSSについて"></blog-post>
  <blog-post title="JavaScriptについて"></blog-post>
</div>
Vue.component('blog-post', {
  props: ['title'], //title属性をコンポーネントのプロパティに追加
  template: `<h3>{{ title }}</h3>` //コンポーネントのプロパティとしてtitleを使用
})

var app = new Vue({
  el: '#app',
})

ブラウザの検証でElementsを確認すると、<h3>title属性で指定した文字列</h3>のようになっているのが確認できます。

プロパティ(props)は、コンポーネントに登録できるカスタム属性です。

HTML側では、blog-postタグのtitle属性に値を指定します。この値をコンポーネントに渡して、使用できるようにしていきます。Vue.js側では、title属性をblog-postコンポーネントのプロパティに追加します。これでコンポーネントのプロパティとして、titleプロパティを使用できるようになりました。templateでtitleを使用します。

Vueインスタンスのdataを渡す

今度は、Vueインスタンスのdataをコンポーネントに渡す方法を見ていきます。

<div id="app">
  <blog-post-array
    v-for="post in posts"
    v-bind:key="post.id"
    v-bind:title="post.title"
  ></blog-post-array>
</div>
Vue.component('blog-post-array', {
  props: ['title'],
  template: `<h3>{{ title }}</h3>`
})

var app = new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'HTML入門' },
      { id: 2, title: 'CSS入門' },
      { id: 3, title: 'JavaScript入門' }
    ]
  }
})

まず、v-forでpostsの中身を1つずつ処理します。今回の肝となるコードは、v-bind:title="post.title"です。v-bindを使ってコンポーネントのプロパティにpost.titleを紐づけています。こうすることで、Vueインスタンスのdataをコンポーネントに渡しています。

単一のルート要素

コンポーネントのtemplateオプションには注意点があります。それは、単一のルート要素が必要ということです。例えば、以下のコードはエラーになります。

Vue.component('blog-post-root', {
  props: ['title', 'content'],
  template: `
    <h3>{{ title }}</h3>
    <div v-html="content"></div>
  `
})

兄弟要素を親要素でラップして、以下のように修正します。このようにすることで単一のルート要素の形になるのでエラーは解消されます。

Vue.component('blog-post-root', {
  props: ['title', 'content'],
  template: `
    <div>
      <h3>{{ post.title }}</h3>
      <div v-html="post.content"></div>
    </div>
  `
})

単一のプロパティでデータを渡す

冒頭でも言いましたが、コンポーネントを使ってブログを作成するとなると、記事のタイトルや投稿内容などのデータをコンポーネントに渡して処理することになります。タイトルや投稿内容だけでなく他のデータも必要になると思います。

例えば、複数のデータをコンポーネントに渡すには以下のようなコードが考えられます。

<div id="app">
  <blog-post
    v-for="post in posts"
    v-bind:key="post.id"
    v-bind:title="post.title"
    v-bind:content="post.content"
    v-bind:publishedAt="post.publishedAt"
    v-bind:comments="post.comments"
  ></blog-post>
</div>

このようなコードは冗長です。代わりに、単一のpostプロパティを紐づけるようにします。

<!-- postプロパティを紐づける -->
<div id="app">
  <blog-post
    v-for="post in posts"
    v-bind:key="post.id"
    v-bind:post="post"
  ></blog-post>
</div>

v-bind:post="post"コンポーネントのpostプロパティに紐づけます。

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div>
      <h3>{{ post.title }}</h3><!-- post.プロパティ名でデータにアクセスする -->
      <div v-html="post.content"></div>
    </div>
  `
})

var app = new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'HTML入門', content: 'HTML入門です' },
      { id: 2, title: 'CSS入門', content: 'CSS入門です' },
      { id: 3, title: 'JavaScript入門', content: 'JavaScript入門です' }
    ]
  }
})

props: ['post']で受け取ります。コンポーネントでは、post.プロパティ名でプロパティにアクセスします。

まとめ

コンポーネントにデータを渡す方法について書きました。記事の内容が多くなりましたが、一つ一つ確認すれば難しくはないと思います。

参考サイト

» HTML入門のまとめはこちらです。