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 } })
変数denshosha
のtemplate
属性がコンポーネントの実体。Vueインスタンスのcomponents
オプションで紐づいている。
詳細は前回記事を参照。
※参考:【Vue.js】コンポーネントにカウンターを仕込む(※dataオプションを無名関数に!) - クモのようにコツコツと
今回これに値を渡して固有名詞(北斗四兄弟名)にした。
こんな感じ。
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 }, // 後略 }
- 変数
denshosha
のtemplate
オプションの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 = "その他"; } }, // 後略 }
- 変数
denshosha
にcreated
オプションを追加 - もし
hokuto4bros
プロパティがなければ - その
hokuto4bros
には「その他」を入れる
これで5つ目のプロパテォが空のコンポーネントに「その他」が表示された!
created
オプションはVueインスタンスが生成されたときに実行されるオプション。
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
属性で変数name
をhokuto4bros
プロパティに適用
コンポーネントが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編) - クモのようにコツコツと
しかしこの方法だと端末やブラウザを超えたデータを保持はできない。本来選挙は複数人で行うものなので別途データベースと連携させるサーバサイド処理必要になってきますね。その方法も調べていきたく。まだまだ道は長いな…。それではまた!
※参考:Vue.jsの習得のためにやったことまとめ
qiita.com