クモのようにコツコツと

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

【Vue.js】コンポーネントにカウンターを仕込む(※dataオプションを無名関数に!)

Vue.jsシリーズ続きです。前回はコンポーネントでハローワールド的一歩を踏みしめました。今回はコンポーネントにカウンターを仕込んでみます。ポイントはdataオプションの値を無名関数にすることです。それではいきましょう!

【目次】

前回記事はこちら

※参考:【Vue.js】コンポーネント事始め(グローバル登録とローカル登録) - クモのようにコツコツと

今回のゴール(コンポーネントにカウンターを仕込む)

今回のゴールはこちら。「北斗神拳伝承者総選挙」の投票ページという設定です。

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

リストにボタンがついていて、クリックすると数値がカウントアップされる。

f:id:idr_zz:20190817080748j:plain

以前のGoogle Chartsとの連携で作ったカウンターと同じ挙動。

※参考:【Vue.js】Google Chartsのグラフと連動させる - クモのようにコツコツと

今回はこのカウンターをコンポーネントの中に仕込んでいる。 最終的にリストに候補者(北斗四兄弟)の固有名を表示したいが、今回はカウンターまで。名前部分は仮で「名無しさん@拳王様崇拝」とした。

HTMLコンポーネントを複製

まずにコンポーネントを複製する。伝承者候補は四兄弟なので4つに複製。

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

HTMLコード

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

前回のコードと構成はほとんど同じ。id名、class名は若干変更したくらい。ただ、コンポーネント名denshoshaが4行になっている。

次にJSコード

var denshosha = {
  template: '<li>名無しさん@拳王様崇拝</li>'
}

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

こちらも前回のコードと構成はほとんど同じ。変数名やelや値を変えた程度。

※参考:【Vue.js】コンポーネント事始め(グローバル登録とローカル登録) - クモのようにコツコツと

このように、コンポーネントはJSで一箇所設定すれば、HTML上のどこに何個配置しても同じものが表示される。修正もJSの一箇所を直せばOKなので共通パーツの使い回しが楽になる!

dataオプションとmethodsオプションでカウンターを仕込む

次にカウンターを仕込む。

JSコード

var denshosha = {
  template: '<li>名無しさん@拳王様崇拝 <button v-on:click="tohyo">推す!</button>→ {{ count }}</li>'
}
  • templateの中にbuttonタグを追加
  • buttonタグの属性にv-on:clickを入れる。値はtohyoとする。
  • 投票ボタンの後ろにマスタッシュタグ{{ count }}。ここに投票数が表示される。

次にdataオプションで初期値、methodsオプションでカウントアップを設定する。
ここでポイントは、いつもはこれらのオプションはVueインスタンスの中に書いていたが、今回は変数denshoshaの中に書く。

var denshosha = {
  template: '<li>名無しさん@拳王様崇拝 <button v-on:click="tohyo">推す!</button>→ {{ count }}</li>',
  data:  {
    count: 0
    }
  },
  methods: {
    tohyo: function() {
      this.count++;
    }
  }
}
  • dataオプションでcountキーの値を0に(初期値)
  • methodsオプションでtokyoキーの値を無名関数に。該当するオブジェクトのcountに1加算++

methodsオプションのキー名tohyoによってHTMLの投票ボタンのv-onの値と紐づく。これでtemplateのマスタッシュタグcountに初期値0が入り、投票ボタンをクリックすると数値が1ずつ加算されるはずが…されない!!

コンポーネントでカウンターに動かすにはもう一つポイント、dataオプションの変更が必要。

dataオプションの値を連想配列→無名関数に変更

もう一つのポイントでコンポーネントのdataオプションは単なる連想配列ではなく無名関数にする必要がある!

コンポーネントの data オプションは関数でなければなりません。各インスタンスが返されるデータオブジェクトの独立したコピーを保持できるためです:

※参考:https://jp.vuejs.org/v2/guide/components.html#data-は関数でなければなりません

このように変更する。

  data: function() {
    return {
        count: 0
    }
  },
  • dataオプションの値を無名関数に
  • returnで戻り値を返す。値は連想配列
  • 戻り値の連想配列はcountキーで値は0

先ほどの連想配列をreturn付きの無名関数で囲う形。これでカウントが動いてくれる。

なお、Vueインスタンスの中身は変更なし。

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
  }
})

完成品

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

リストの「名無し@〜」のあとに投票ボタンと投票数を追加。しかし、こちら、なんとHTMLファイルは何も変更していない。JSの変更のみで済む。コンポーネントの利点。

最後に

コンポーネントの中にカウンターを仕込む。ポイントは

  • dataオプションとmethodsオプションはVueインスタンスではなくtemplateのある変数の場所に書く
  • dataオプションは連想配列ではなく無名関数にする

次回は「名無しさん@拳王様崇拝」の部分に候補者の固有名(北斗四兄弟)を表示したく。それではまた!

※続き書きました!

www.i-ryo.com