はじめに
Nuxt.jsは、Webページのユーザーインタフェース(UI)フレームワークであるVue.jsに、Webページの作成に必要なUI以外の機能を追加して、まとめて提供するフレームワークです。そのため、Nuxt.jsの機能を使いこなすためには、まずVue.jsの利用方法を知っておく必要があります。
Vue.jsでは、データとWebページの表示を関連付けるデータバインディングやイベント処理、条件分岐や繰り返しなど、動的なWebページを作成するための機能が提供されます。本記事では、こういったVue.jsの基本的な利用方法を説明します。
対象読者
- Nuxt.jsを何から始めていいかわからない方
- Vue.js未経験の方
- ひとまずVue.jsやNuxt.jsで動的なWebページを作ってみたい方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
-
Windows 10 64bit版
- Node.js v10.16.2 64bit版
- Nuxt.js 2.8.1
- Vue.js 2.6.10
- Microsoft Edge 44.18362.1.0
サンプルコードは、Nuxt.jsのCLIツール(create-nuxt-app)で生成したプロジェクトをもとに実装しています。CLIツールの利用法やプロジェクト構成などの詳細は、前回記事を参照してください。
サンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「npm run dev」コマンドを実行して、Webブラウザーで「http://localhost:3000/」を開きます。
Webページとデータを関連付けるVue.jsのデータバインディング(1)
動的なWebページでは、ユーザーの入力をデータに反映したり、データをWebページに表示したりする処理が必要となります。Vue.jsではこういった処理を、Webページとデータを関連付ける「データバインディング」で実現します。
データバインディングの基本
Vue.jsでデータバインディングを行う基本的な方法を、図1のサンプルで説明します。テキストボックスに入力されたURLを、ハイパーリンクの文言とリンク先に反映します。
図1のWebページを実装したファイルの内容を、リスト1に示します。
<template> <div class="container"> <h1>基本的なデータバインディング</h1> <input v-model="url" placeholder="URL"> <!--(1)--> <a v-bind:href="url" target="_blank"> <!--(2)--> {{ url }}へのリンク <!--(3)--> </a> </div> </template> <script> export default { data() { return { url: 'https://codezine.jp/' // (4) } } } </script> (以下略)
ロジックを記述する<script>で、URLの文字列を格納するurl変数(4)を定義します。表示内容のテンプレートを記述する<template>では、(1)~(3)の3種類の方法でurl変数を参照しています。(1)の「v-model」はテキストボックスのような入力部品の内容、(2)の「v-bind」はhrefなどのタグ属性、(3)の{{ }}(2重の中カッコ)はWebページの表示内容に、変数内容を関連付け(データバインディング)します。このうちv-modelは、入力部品の内容と変数の内容を双方向に同期する、いわゆる双方向データバインディングを実現します。
v-modelやv-bindのように「v-」から始まってHTMLタグに設定するVue.jsの属性を「ディレクティブ」と呼びます。以下では、v-modelとv-bindディレクティブについて補足説明していきます。
Webページとデータを関連付けるVue.jsのデータバインディング(2)
さまざまな入力部品とv-modelディレクティブ
さまざまな入力部品でv-modelディレクティブを利用する例を、図2のサンプルで説明します。入力部品に入力した内容が、入力部品のすぐ下に表示されます。
図2で利用しているv-modelディレクティブの記述をリスト2に示します。
<h3>テキストボックス</h3> <!--(1)--> <input v-model="text1"> <h3>複数行テキストボックス</h3> <!--(2)--> <textarea v-model="text2"></textarea> <h3>チェックボックス</h3> <!--(3)--> <input type="checkbox" id="checkbox" v-model="checkboxValue"> <label for="checkbox">私はNuxt.jsが好き</label> <h3>ラジオボタン</h3> <!--(4)--> <input type="radio" id="radio1" value="vue" v-model="radioValue"> <label for="radio1">Vue.js</label> <input type="radio" id="radio2" value="angular" v-model="radioValue"> <label for="radio2">Angular</label> <input type="radio" id="radio3" value="react" v-model="radioValue"> <label for="radio3">React</label> <h3>選択</h3> <!--(5)--> <select v-model="selectValue"> <option disabled value=""></option> <option value="vue">Vue.js</option> <option value="angular">Angular</option> <option value="react">React</option> </select> <h3>複数チェックボックス</h3> <!--(6)--> <input type="checkbox" id="checkbox1" value="vue" v-model="checkboxArray"> <label for="checkbox1">Vue.js</label> <input type="checkbox" id="checkbox2" value="angular" v-model="checkboxArray"> <label for="checkbox2">Angular</label> <input type="checkbox" id="checkbox3" value="react" v-model="checkboxArray"> <label for="checkbox3">React</label> <h3>複数選択</h3> <!--(7)--> <select v-model="selectArray" multiple> <option value="vue">Vue.js</option> <option value="angular">Angular</option> <option value="react">React</option> </select>
テキストボックスは、通常の(1行の)テキストボックス(1)のほか、<textarea>タグによる複数行テキストボックス(2)でも同様にv-modelディレクティブが利用できます。
(3)はチェックボックスの例です。v-modelで設定した変数に、チェック状態(trueまたはfalse)が格納されます。
(4)のラジオボタンや(5)の選択では、選択されたラジオボタンや選択肢に対応する値(value属性の値)が、v-modelで設定した変数に格納されます。
複数選択に対応した(6)のチェックボックスや(7)の選択では、v-modelに配列変数を設定すると、選択された複数の値が配列に格納されます。
[補足]v-modelディレクティブの修飾子
v-modelディレクティブには、入力内容が確定した時のみデータを更新する「.lazy」、入力内容を数字に変換する「.number」、入力された文字列前後の空白を削除する「.trim」の修飾子を付与できます。修飾子を付与する例をリスト3に示します。
<input v-model.number="number1">
修飾子の詳細は、公式ドキュメントを参照してください。
v-bindディレクティブでクラスやスタイルを設定
v-bindディレクティブを利用すると、HTMLタグの任意の属性に、Vue.jsの変数内容を反映させられます。特に、CSSのクラス(class属性)とスタイル(style属性)では、JavaScriptオブジェクトを利用してより詳細な設定ができます。この例を、図3のサンプルで説明します。チェックボックスでクラスの適用有無を切り替えたり、テキストボックスでスタイル(文字色)を設定したりできます。
まず、class属性のデータバインディング記述を、リスト4に示します。
<label for="checkbox1" v-bind:class="{ 'color-red' : isChecked }"> 文字を赤色にする </label>
v-bind:classに設定された「{ 'color-red' : isChecked }」は、isChecked変数がtrueの時に、CSSクラス「color-red」が適用されることを意味します。この記述で、適用されるCSSクラスを条件によって切り替えられます。
次に、style属性のデータバインディング記述を、リスト5に示します。
<div v-bind:style="{ color: fontColor }"> 色:{{ fontColor }} </div>
v-bind:styleに設定された「{ color: fontColor }」は、CSSのcolorプロパティに、fontColor変数の内容を設定することを意味します。サンプルではfontColor変数がテキストボックスにデータバインディングされているため、テキストボックスに色名を入力すると、色名に対応した色で文字列が表示されます。
[補足]算出プロパティの利用
Vue.jsでは、算出プロパティ(変数をもとに算出した読み取り専用のプロパティ)を定義できます。例えば、リスト4、5でv-bindディレクティブに設定されている内容は、リスト6の通り算出プロパティにできます。
export default { (略) computed: { // 算出プロパティ computedClass() { return { 'color-red' : this.isChecked }; // this.isCheckedから算出 }, computedStyle() { return { color: this.fontColor }; // this.fontColorから算出 } } }
リスト6の算出プロパティcomputedClass、computedStyleは、リスト7の通りv-bindディレクティブに設定できます。
<!-- class --> <label for="checkbox1" v-bind:class="computedClass"> 文字を赤色にする </label> <!-- style --> <div v-bind:style="computedStyle"> 色:{{ fontColor }} </div>
v-onディレクティブによるイベント処理
Vue.jsのイベント処理は、v-onディレクティブを利用して「v-on:<イベント名>」形式で記述します。v-onディレクティブの利用方法を、ボタンのクリックとキー入力のイベントハンドラーを実装した図4のサンプルで説明します。
v-onディレクティブには、イベントハンドラーのメソッド名を設定します。リスト8では、クリックイベントに対応する「v-on:click」に、イベントハンドラーのgreetメソッドを設定しています。
<button v-on:click="greet">ご挨拶</button>
イベントハンドラーに与える引数を含めてv-onディレクティブに設定することもできます。特に、JavaScriptのイベント変数が必要な場合は、引数に「$event」を設定します。リスト9では、キーが押下後に離された時のイベント「v-on:keyup」のイベントハンドラーで、押下されたキーの文字列をイベント変数から取得して画面に表示します。処理の詳細はサンプルコードを参照してください。
<input v-on:keyup="onKeyUp($event)">
[補足]イベント修飾子とキー修飾子
v-onディレクティブには、イベント処理の内容を補足する「イベント修飾子」を追加できます。フォームのサブミットボタンにクリックイベントを設定したリスト10の例では、v-on:clickに「.prevent」というイベント識別子を追加して、デフォルトの動作(=フォームのSubmit)をキャンセルしています(イベント変数のpreventDefaultメソッドと同じ効果です)。
<form> <input type="submit" v-on:click.prevent="onFormSubmit" value="Submitボタン"> </form>
また、v-onディレクティブに「キー修飾子」を追加して、特定のキーに対するイベントを設定できます。リスト11では、v-on:keyupに「.enter」というキー修飾子を追加して、Enter(改行)キーが押下された場合のみkeyupイベントが発生するようにしています。
<input v-on:keyup.enter="onKeyUpEnter">
イベント修飾子やキー修飾子の詳細は、イベントに関する公式ドキュメントを参照してください。
[補足]v-bindとv-onの省略記法
v-bindとv-onでは省略記法を利用できます。省略記法では、「v-bind:href」を「:href」、「v-on:click」を「@click」と記述します。
条件分岐と繰り返し
Vue.jsでは、「v-if」ディレクティブで条件分岐、「v-for」ディレクティブで繰り返しを利用できます。以下で利用方法を説明していきます。
v-ifディレクティブによる条件分岐
v-ifディレクティブの利用方法を、図5のサンプルで説明します。ラジオボタンの選択で、表示される文言の内容が変わります。
図5のサンプルにおけるv-ifディレクティブの記述を、リスト12に示します。
<div v-if="radioValue === 'ios'"> <!--(1)--> あなたはiOSが好きなんですね。 </div> <div v-else-if="radioValue === 'android'"> <!--(2)--> あなたはAndroidが好きなんですね。 </div> <div v-else> <!--(3)--> その他が好きとはマニアックですね。 </div>
(1)のv-ifディレクティブで、ラジオボタンの選択値が格納されるradioValueが「ios」の場合に表示される内容を記述します。v-ifディレクティブの直後に、(2)のv-else-ifディレクティブや、(3)のv-elseディレクティブを記述すると、複数条件の分岐を記述できます。
v-forディレクティブによる繰り返し
v-forディレクティブの利用方法を、図6のサンプルで説明します。配列に格納されたスマートフォンの情報を一覧表示します。
スマートフォンの情報を格納するphoneList配列は、<script>でリスト13の通り記述して、id、vendor、modelのプロパティを含むJavaScriptオブジェクトの配列を設定します。
phoneList: [ { id: 1, vendor: 'Apple', model: 'iPhone XS' }, { id: 2, vendor: 'Apple', model: 'iPhone XS Max' }, (略) ]
phoneList配列の内容を一覧表示するv-forディレクティブの記述は、リスト14の通りです。
<ul> <li v-for="phone in phoneList" v-bind:key="phone.id"> <!--(1)--> {{ phone.vendor }}: {{ phone.model }} <!--(2)--> </li> </ul>
(1)でv-forディレクティブに「phone in phoneList」と設定すると、phoneList配列の各要素をphone変数として取得できるので、(2)の通り{{ }}記述でphone変数のプロパティを指定して画面表示できます。
なお、リスト14(1)の「v-bind:key」は、リストの各データを一意に表すキーとなるデータ項目を設定する記述です。Vue.jsはv-bind:keyに設定された項目で各データを一意識別して、配列の更新時に、更新された箇所だけを再描画します。
まとめ
本記事では、JavaScriptフレームワークNuxt.jsがUIの構築に利用するVue.jsについて、基本的な利用方法を説明しました。データバインディングやイベント処理、条件分岐や繰り返しの機能を利用して、動的なWebページをVue.jsの機能で作成できます。
次回は、Webページ遷移を実現する、Nuxt.jsのルーティング機能を説明します。

