vue.jsでHTMLの流し込みを簡単に!コンポーネント化でパターン違いも簡単!

こんにちは、ナカムラです。
スタティックのHTMLページを作成している中で、商品情報など、
同じレイアウトを繰り返すコンテンツがあります。
数が少なければ手作業で書き込めば良いですが、10件、20件ともなるとなかなか大変な作業になります。
そこで今回は、掲載情報をデータ化して、vue.jsを使ってレンダリングしてしまおうと思います。

DEMO

See the Pen vue.jsのコンポーネント by Nakamura (@takayo-nakamura) on CodePen.

リストレンダリング

ここでは以下のようなデータを、単純にv-forで表示しています。
この後、コンポーネント化した時にも使います。

new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'りんご' , image: 'https://placehold.jp/150x150.png' },
      { id: 2, title: 'みかん' , image: 'https://placehold.jp/150x150.png' },
      { id: 3, title: 'ぶどう' , image: 'https://placehold.jp/150x150.png' }
    ]
  }
})
<div v-for="item in posts">
   id:{{ item.id }},{{ item.title }},{{ item.image }}
 </div>

コンポーネント化する

わざわざコンポーネント化しなくてもリストは作れますが、
同じデータでも配置する場所によって掲載したい要素が異なる場合があります。
コンポーネント化してテンプレートを分けることで、一つのデータでレイアウトパターンをいくつでも作れるようになります。

※コンポーネントについては公式サイトをご確認ください。
コンポーネントの基本 — Vue.js

コンポーネント:1

idとtitleだけを表示させたパターンです。
コンポーネント名はtext-postです。

Vue.component('text-post', {
  props: ['post'],
  template: '<div class="item">id:{{ post.id }}{{ post.title }}</div>'
})

コンポーネント:2

画像があるパターンで、classも追加しています。
コンポーネント名はimage-postです。

Vue.component('image-post', {
  props: ['post'],
  template: '<div class="item item-image"><img :src="post.image" alt="イメージ">id:{{ post.id }}<span class="item__title">{{ post.title }}</span></div>'
})

コンポーネント化のポイント

<item-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" ></item-post>

最初のリストレンダリングと違う箇所がありますね。

(1)書き出したい箇所のHTMLタグはコンポーネント名になります。

(2)v-bind:key="post.id":キーを設定。
2.2.0 以降で、コンポーネントで v-for を使用するとき、key は必須です。
詳しくはこちら
リストレンダリング — Vue.js

(3)v-bind:post="post": コンポーネントのpropsオプションとv-bindで連携させます。
詳しくは下記リンク先の、「単一のルート要素」のこの部分です。

そうなったら、<blog-post> コンポーネントをリファクタする好機かもしれません。代わりに、単一の post プロパティを受け入れる形にするのです

コンポーネントの基本 — Vue.js

最後に

HTMLメールなどのjavascriptが使えない環境では、レンダリングしたHTMLのソースコードをコピペして使います。
Webサイトならそのまま組み込んで使うこともできます。
順番の入れ替えなどの調整もしやすいので一度作っておくと便利です。

昔はエクセルで整形していましたが、コピペの際にダブルクォーテーションが入ってしまう問題があったり、何かとやりにくいので自動化できるものはどんどん取り入れていきたいと思います。