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

HTML,CSSの入門記事やブログのカスタマイズについてアウトプットしています。

 メニュー

【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.プロパティ名でプロパティにアクセスします。

まとめ

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

参考サイト