【VueとNuxt】v-on, v-if, v-bind, v-modelの使い方紹介
Vue と Nuxt の使い方 2 つめの記事です!
続きものの記事になるので、前回の記事をまだ見てない方は先にそちらをみることをおすすめします。
【Vue と Nuxt】環境構築と components, layouts の使い方紹介
前回の記事では、単なる HTML と CSS がほとんどで JavaScript(JS)っぽいことをしていません。今回からは JS のフレームワークらしく動的な処理を行っていきます。
ということで、本記事では Nuxt と Vue でよく使うディレクティブ、v-on や v-model などについて説明します。
今回もこちらの書籍も参考にさせていただきました。
ディレクティブとは
ディレクティブとは簡単に言うと、v-からはじまる Vue 特有の属性です。
ディレクティブは v- から始まる特別な属性です。ディレクティブ属性値は、単一の JavaScript 式を期待します(ただし、v-for は例外で、これについては後から説明します)。ディレクティブの仕事は、属性値の式が変化したときに、リアクティブに副作用を DOM に適用することです。
公式より引用:ディレクティブ
公式をみると、けっこうたくさんのディレクティブがあります。
いくつか代表的なものを列挙します。以下はディレクティブのなかでもリアクティブディレクティブというものに分類されます。
- v-on
- v-bind
- v-model
- v-if
- v-text
- v-html
- v-style
本記事では上4つを紹介します。
v-on, v-if の使い方
まず v-on と v-if を同時に試していきます。
v-on はイベントハンドリングのために使われます。onclickのようなイメージです。今回はボタンクリックに反応し後述する関数を呼び出します。
v-if はそのままで条件付けを行って場合わけができます。今回はフラグによって表示するか否かを判定するために使います。
試してみましょう。
index.vueを以下のように書き換えます。
<template>
<div class="container">
<h1 class="title">テストページ</h1>
<h2 class="subtitle">Nuxtお試し中</h2>
<button @click="displayMessage">Click!</button>
<br />
<h2 v-if="show_flg" class="message">{{ message }}</h2>
<nuxt-link to="/next">次ページへ</nuxt-link>
</div>
</template>
<script>
export default {
data() {
return { message: 'Hello', show_flg: false }
},
methods: {
displayMessage() {
this.show_flg = true
}
}
}
</script>
<style>
.message {
font-size: 50px;
margin: 20px;
}
.container {
margin: 20px;
}<template>タグ内に<button>と<h2>をそれぞれ追加しました。<script>内ではdata()とmethodsを追記しました。
あとは、見やすさのために<style>内も少しいじってます。
<script>の変更箇所についてざっくり説明します。
まずdataというのはオブジェクトでここに追加されたプロパティ(リアクティブデータ)はリアクティブシステムに追加されます。
リアクティブシステムというのは、変更を監視/検知して、必要に応じて再レンダリングするためのものです。
dataにはmessage="Hello"とshow_flgを追加してます。
methodsはその名のとおり関数を定義する場所です。今回はボタンクリック時にフラグを変更する関数としてdisplayMessageを定義しました。
どうなるか見てみましょう。
ボタンクリック前がこんな感じです。show_flgが false なので message は表示されていません。

ボタンをクリックすると以下のようにdisplayMessageが呼び出され、show_flgが true に書き換わり、message で定義した文字列が表示されます。

v-bind, v-model の使い方
v-bind を使うことで HTML のタグ内の属性を書き換えることができます。属性というのは HTML のタグの中にかくclassやvalueなどです。
さっそくやってみましょう。せっかくなので前回作成したnext.vueのほうでやってみます。
<template>
<div class="container">
<h1 class="title">Nextページ</h1>
<h2 class="subtitle">2ページ目</h2>
<p>v-bindパターン:[{{ message1 }}]</p>
<input v-bind:value="message1" type="text" />
</div>
</template>
<script>
export default {
data() {
return {
message1: 'v-bindは属性を変えられる',
}
},
methods: {
changeInput() {
this.message = 'v-modelだよ'
}
}
}
</script>
<style>
input {
margin: 30px 0px;
}
/* <!-- 省略 --> */<input>タグを新たに追加し、v-bind:valueとしてvalueにdataで定義したmessage1を指定している。
これでmessage1で定義されている文字列が入っている入力ボックスが以下のように表示される。

次は v-model です。v-model は v-bind と v-on の組み合わせと考えることができます。
どういうことかというと、v-bind では data()で定義された値を参照しているだけですが、v-on と組み合わせることで v-bind で参照された値を書き換えます。
ちょっと言葉でうまく説明できないので、実際にみたほうが早いかもしれないです。
コードはこんな感じです。
<template>
<div class="container">
<h1 class="title">Nextページ</h1>
<h2 class="subtitle">2ページ目</h2>
<p>v-bindパターン:[{{ message1 }}]</p>
<input v-bind:value="message1" type="text" />
<br />
<p>v-modelパターン:[{{ message2 }}]</p>
<input v-model="message2" type="text" />
</div>
</template>
<script>
export default {
data() {
return {
message1: 'v-bindは属性を変えられる',
message2: 'v-modelは双方向バインド',
}
},
methods: {
changeInput() {
this.message = 'v-modelだよ'
},
},
}
</script>ページはこのようになります。

v-bind の場合は入力ボックスの内容をブラウザから書き換えても、<p>タグで表示しているmessage1の内容は変化しません。
一方で、v-model のほうの入力ボックスの内容を書き換えると、リアルタイムで<p>タグで表示しているmessage2の内容も変化しています。
書き換えを試した結果はこんな感じです。

なので、v-bind と v-model の違いは入力内容を動的に JS で定義された変数に反映するかどうかです。
まとめ
今回は Vue でよく使うディレクティブをいくつか紹介しました。
ディレクティブを使うと Vue らしさがでますね。
簡単に動的処理が実行できるんで楽しいです。
ぜひ試してみてください〜