例えば、コンポーネントを使ってブログを作成するとなると、記事のタイトルや投稿内容などのデータをコンポーネントに渡して処理することになります。今回は、コンポーネントにデータを渡す方法について書きます。
カスタム属性としてデータを渡す
<!-- 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.プロパティ名
でプロパティにアクセスします。
まとめ
コンポーネントにデータを渡す方法について書きました。記事の内容が多くなりましたが、一つ一つ確認すれば難しくはないと思います。