アプリを作ろう(8):VueでのJavaScript連携
・templateの中でscriptの変数値をどうやって使うのか
・属性値として変数値をどうやって使うのか
・なぜcolor='{{ background }}'のようには書けないのか
改めてv-date-pickerのソースを見てみましょう。
<template>
<v-app>
<v-container>
<v-card>
<h1>Hello Nuxt</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
<script>
export default {
data: () => ({
date: "",
}),
};
</script>
scriptの中身については理解できたと思いますが、これだけでは実際の表示部分であるtemplateに反映されません。template部分でどのようにscriptを利用するのかを解説していきます。
変数値の利用:二重括弧
scriptではオブジェクトをexport defaltでnuxtから使えるようにしました。その中にはdataという名前で関数が定義されています。この関数はオブジェクトを返す関数となっていて、例ではdateという名前で空文字が返るようになっています。
Nuxtではこのように定義されたdataの中に入っている変数をtemplateの中で自由に利用することができます。ただ、利用するルールは決められていて、二重括弧:{{ }} の中に変数名を書くと利用できます。
試しに下記のようにソースコードを変えてみましょう。
<template>
<v-app>
<v-container>
<v-card>
<h1>Hello {{ message }}</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
<script>
export default {
data: () => ({
date: "",
message: "Nuxt",
}),
};
</script>
変更点は二つあります。dataの返すオブジェクトにmessageを追加しました。また、h1タグの中に二重括弧でmessageを指定しています。このように指定することでtemplateの中で変数値を呼び出すことができます。表示結果は下記のようになります。
さて、二重括弧の中には変数名だけではなく、JavaScriptの式を書くこともできます。例えば次のように変えてみましょう。
<h1>Hello {{ message + (123 + 456) }}</h1>
表示結果は下記のようになります。
messageの後ろに123+456の結果が表示されています。例えばdataの中にある変数値に数字を指定した場合はその演算結果が表示されます。このように二重括弧の中だけはscriptのように扱うことができるのです。
属性値の指定:v-bind
v-cardはcolorを指定することで色を変更することができます。例えば以下のようになります。
<template>
<v-app>
<v-container>
<v-card color="blue">
<h1>Hello Nuxt</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
<script>
export default {
data: () => ({
date: "",
}),
};
</script>
実行結果は下の通りです。
このcolorの属性値にdataの中の変数値を使うにはどうすれば良いでしょうか。パッと思いつくのは color="{{ background }}"のように二重括弧で囲うような方法ですが、これはNuxtでは動作しません。この理由は下記の通りとなります。ちょっと長いですので、興味が無ければv-bindまで飛ばしてください。
h1タグの中身などのようにHTMLで表示されるところはある程度自由に文字列を表記して構いません。文字列はそのまま表示されるためエラーにならないためです。また、間違えていた場合にはブラウザで表示したときに気付きやすいという側面もあります。そのため、文字列の中に二重括弧で埋め込むようなことをしても問題は少ないと言えます。
一方でHTMLの属性値はある程度のルールを守らないと正常に機能しません。例えばcolorは色の名前と一致しないといけませんし、widthなどは数値が入っていないといけません。このようなルールが決められているものに対して二重括弧で埋め込むようなことをすると文字列連結のミスによりバグを引き起こしやすくなります。
例えば色の指定にlight-blueを指定しようとして、二重括弧ルールのもと下記のように記述したとします。
color="light- {{ blue }}"
この場合、light-の後ろにスペースが含まれているため、指定はcolor="light- blue"となり、light-blueの指定にはなりません。そして厄介なことにこの場合はブラウザ側がblueと解釈してしまいます。おまけにblueとlight-blueの違いは見た目でほとんど分からないので、ブラウザ確認でも気付きません。色の違いが分かるデザイナーが最終確認したときにバグとして扱われてしまったりして、手戻りが多くなったりします。このようなバグを引き起こしやすいという問題から属性値に二重括弧は用いられていません。
さて、ではどうやって属性値に変数の値を用いるのでしょうか。Vueでは属性値の前に「v-bind:」を付けることで属性値の中身全てがJavaScriptの式として扱われます。
<template>
<v-app>
<v-container>
<v-card v-bind:color="background">
<h1>Hello Nuxt</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
<script>
export default {
data: () => ({
date: "",
background: "blue",
}),
};
</script>
scriptの中にbackgroundとして色の名前の変数を用意し、それをv-bindを使ってcolorに適用しています。ちなみに、HTMLやブラウザとしてv-bind:には何の意味もなく、コロン(:)を付けることで特別な意味を持つわけではありません。コロンただの一文字に過ぎないのです。Nuxtがv-bind:で始まっている属性値を見つけるとJavaScriptで処理してくれるだけです。
さて、light-blueに変えたい場合は下記のようにもできます。
v-bind:color="'light-' + background"
v-bindの中はJavaScriptの式として扱われるので文字列連結が行われます。足し算の式なので+の前後にスペースが入っていても問題ありません。もちろん、文字列の中にスペースが紛れてしまえばバグになりますが、二重括弧で引き起こされるようなバグよりは圧倒的に頻度が低いでしょう。
v-bindはVue/Nuxtでの開発で頻繁に使うため、コロン(:)の一文字に省略できます。
<template>
<v-app>
<v-container>
<v-card :color="background">
<h1>Hello Nuxt</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
scriptは省略します。分かってしまえば簡単ですが、分からない人からするとコロンが1文字先頭に付いただけで大きく挙動が変わることに混乱するかもしれません。
この省略は非常に便利です。筆者は実際にv-bindと書いたことは一度もありません。慣れるようにしてv-bindという言葉は忘れてしまっても問題ありません。
さて、v-modelまで到達できませんでした。次回はv-onとメソッド呼び出し、続けてv-modelまでを説明していきます。