クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【Vue.js】コンポーネントにpropsオプションで値を渡す

Vue.jsシリーズの続きです。前回はコンポーネントにカウンターを仕込みました。今回はコンポーネントに値を渡してみます。propsオプションを使います。それではいきましょう!

【目次】

前回記事はこちら

※参考:【Vue.js】コンポーネントにカウンターを仕込む(※dataオプションを無名関数に!) - クモのようにコツコツと

前回のおさらい

前回の完成物

See the Pen Vue components 4 by イイダリョウ (@i_ryo) on CodePen.

投票ボタンを押すとカウンターが動いて投票数が変わる。この時点では同じコンポーネントを4つ複製しているだけなので名前はすべて「名無し@〜」。

<div id="hokuto">
  <h1>北斗神拳伝承者総選挙</h1>
  <p>あなたの推しメンに投票しよう!</p>
  <ul>
    <denshosha></denshosha>
    <denshosha></denshosha>
    <denshosha></denshosha>
    <denshosha></denshosha>
  </ul>
</div>

denshoshaという独自のタグが4つある。これがコンポーネント。ここの表示がJSに書かれているコンポーネント設定に置き換わる。

var denshosha = {
  template: '<li>名無しさん@拳王様崇拝 <button v-on:click="tohyo">推す!</button>→ {{ count }}</li>',
  data: function() {
    return {
    count: 0
    }
  },
  methods: {
    tohyo: function() {
      this.count++;
    }
  }
}

new Vue({
  el: '#hokuto',
  components: {
    'denshosha': denshosha
  }
})

変数denshoshatemplate属性がコンポーネントの実体。Vueインスタンスのcomponentsオプションで紐づいている。

詳細は前回記事を参照。

※参考:【Vue.js】コンポーネントにカウンターを仕込む(※dataオプションを無名関数に!) - クモのようにコツコツと

今回これに値を渡して固有名詞(北斗四兄弟名)にした。

f:id:idr_zz:20190822051859j:plain

こんな感じ。

propsオプションで値を渡す

完成品

See the Pen Vue components 5 by イイダリョウ (@i_ryo) on CodePen.

「名無し@〜」が北斗四兄弟「ラオウ」「トキ」「ジャギ」「ケンシロウ」になった!投票ボタンを押すと票数が上がる。これでようやく北斗神拳伝承者を決める総選挙が成立したw

HTMLコード

<div id="hokuto">
  <h1>北斗神拳伝承者総選挙</h1>
  <p>あなたの推しメンに投票しよう!</p>
  <ul>
    <denshosha hokuto4bros="ラオウ"></denshosha>
    <denshosha hokuto4bros="トキ"></denshosha>
    <denshosha hokuto4bros="ジャギ"></denshosha>
    <denshosha hokuto4bros="ケンシロウ"></denshosha>
  </ul>
</div>

denshoshaコンポーネントの中にhokuto4brosという独自の属性(プロパティ)を書いて値に固有名詞(北斗四兄弟の名前)を入れている。この値を受け取って表示する仕掛けをJSに書いている。

JSコード

var denshosha = {
  template: '<li> {{ hokuto4bros }} <button v-on:click="tohyo">推す!</button>→ {{ count }}</li>',
  props: {
    hokuto4bros: String
  },
// 後略
}
  • 変数denshoshatemplateオプションのliタグをマスタッシュタグにする。値はhokuto4bros
  • propsオプションでコンポーネントのプロパティhokuto4brosを設定。値はデータの型で文字列String

これでliタグの中身にコンポーネントのプロパティhokuto4brosの値が読み込まれた!

※参考:プロパティ — Vue.js

createdオプションで値なしの処理を追加

コンポーネントに値がない場合の例外処理を設定してみる。

See the Pen Vue components 6 by イイダリョウ (@i_ryo) on CodePen.

一番下の「その他」がその事例。

HTMLコード

<div id="hokuto">
  <h1>北斗神拳伝承者総選挙</h1>
  <p>あなたの推しメンに投票しよう!</p>
  <ul>
    <denshosha hokuto4bros="ラオウ"></denshosha>
    <denshosha hokuto4bros="トキ"></denshosha>
    <denshosha hokuto4bros="ジャギ"></denshosha>
    <denshosha hokuto4bros="ケンシロウ"></denshosha>
    <denshosha></denshosha>
  </ul>
</div>

5つ目のコンポーネントdenshoshaにはプロパティが入っていない。

JSコード

var denshosha = {
  template: '<li> {{ hokuto4bros }} <button v-on:click="tohyo">推す!</button>→ {{ count }}</li>',
  props: {
    hokuto4bros: String
  },
  created: function () {
    if (this.hokuto4bros == null) {
      this.hokuto4bros = "その他";
    }
  },
// 後略
}
  • 変数denshoshacreatedオプションを追加
  • もしhokuto4brosプロパティがなければ
  • そのhokuto4brosには「その他」を入れる

これで5つ目のプロパテォが空のコンポーネントに「その他」が表示された!

createdオプションはVueインスタンスが生成されたときに実行されるオプション。

※参考:Vue インスタンス — Vue.js

v-forでループしてv-bindでプロパティに配列の値を入れる

さて、このままだとコンポーネントをいくつも書いて値を書かなければならない。今回はliタグの文字という単純な構成なため直にliで書いちゃえばいいじゃん、という気になってくる。これをv-forでループしてv-bindでプロパティに配列の値を入れてみる。

See the Pen Vue components 7 by イイダリョウ (@i_ryo) on CodePen.

見た目はこれまでと変わらない。

HTMLコード

<div id="hokuto">
  <h1>北斗神拳伝承者総選挙</h1>
  <p>あなたの推しメンに投票しよう!</p>
  <ul>
    <denshosha v-for="name in brosname" v-bind:hokuto4bros="name"></denshosha>
  </ul>
</div>
  • denshoshaコンポーネントにv-for属性とv-bind:hokuto4bros属性
  • v-for属性でbrosname配列をループし変数nameに入れる
  • v-bind属性で変数namehokuto4brosプロパティに適用

コンポーネントが1つになってスッキリ!hokuto4brosプロパティはv-bindで変数nameを指定し、その変数v-bindはJSにある配列brosnameに紐づける。

JSコード(変数denshoshaは変更なし)

new Vue({
  el: '#hokuto',
  data: {
     brosname: ['ラオウ','トキ','ジャギ','ケンシロウ']
  },
  components: {
    'denshosha': denshosha
  }
})
  • Vueインスタンスにdataオプションでbrosname設定。
  • brosnameの値は配列で値は固有名詞(北斗四兄弟の名前)

これでhokuto4brosプロパティの値(変数name)に配列brosnameの値が入れる処理を配列brosnameの回数分ループする。

ループv-forについてはこちら

※参考:【Vue.js】イベント(v-on)、分岐(v-show、v-if)、ループ(v-for)をやってみた! - クモのようにコツコツと

属性指定v-bindについてはこちら

※参考:【Vue.js】v-bindでclass名を動的に追加、削除する!(北斗の拳の名言編) - クモのようにコツコツと

最後に

コンポーネントで共通化パーツを設定し、その中の固有な内容を配列から読み込んでループする、とい処理をすることでHTMLがすごくすっきりしました!コンポーネントはVue.jsだけででなくAnglarやReactなどJSフレームワーク全般でポイントになってくる概念と思うので、今後もいろいろ試していきたく思います。

なお、今の状態だとページをリロードしたときに投票の値はリセットされてしまう。解決策としては以前の記事のようにlocalStrageに値を保存すると保持させる方法がありますね。

※参考:【Vue.js】localStorageと連携したTodoリストを読み解く(HTML、CSS編) - クモのようにコツコツと

しかしこの方法だと端末やブラウザを超えたデータを保持はできない。本来選挙は複数人で行うものなので別途データベースと連携させるサーバサイド処理必要になってきますね。その方法も調べていきたく。まだまだ道は長いな…。それではまた!