作成: @kiriem_
Vue.js は JavaScript のライブラリで、比較的簡単にWebアプリケーションを開発することができます。今回は、Vue.jsを使って簡単なクイズアプリを作ってみましょう。
詳しく学びたい方は、こちらの公式ドキュメントにあるチュートリアルを見てください。
アプリ開発を始める前に、開発環境を整えましょう。
Visual Studio Code をインストールする
GitHub からリポジトリをクローン(ダウンロード)する。
VSCode を開く。
Google Chrome をインストールする(インストールされていない人向け)
これから開発していくアプリの具体的なイメージを持つために、まずはデモ版を触ってみましょう。
index.html
を Google Chrome で開く。アプリケーションを開発するために必要となるプログラムの基本的な事柄を理解しましょう。
今回使う言語は HTML
, CSS
, JavaScript
です。それぞれ別々の役割を持っています。
HTML
: ページの骨子を作るためのマークアップ言語。CSS
: ページのデザイン(色や配置など)をするための言語。JavaScript
: ページの動き(ボタンを押したときにすることや、何を表示するかを決めるなど)をするための言語。それぞれの言語をそのまま使ってプログラムを書くこともできますが、覚えることが膨大で大変になるので、今回はかんたんに使うためにフレームワーク
を利用します。
サンプルファイルには事前に Bootstrap と Vue.js が使えるようになっています。特に意識せずプログラムを開発していきましょう。
プログラミングは頭で理解するより手を動かしたほうが身につきます。さっそく作っていきましょう。
base.html
を開き、ソースコードを全選択してコピーし、 app.html
にペーストする。app.html
を保存する。Windows では Ctrl+S キーを、 macOS の場合は Cmd+S
キーを押す。ファイル名を app.html
にして、 base.html
と同じフォルダに保存する。htmlファイルの解説をします。まずは前半部分です。 一般的なHTMLファイルは次のような構成になっています。
次に app.html を見てください。 <head> </head>
タグの部分だけを抜粋しました。
<head></head>
で囲まれた部分は、基本的には目に見えるものではなくファイルの設定などをする場所です。今回は Bootstrap を読み込んだり、サイトのアイコン(ブラウザのタブに表示されるもの)やOGP(SNSでシェアしたときに表示される画像)の設定をしています。基本的にはいじらないようにしましょう。
OGPの例:
一箇所だけ修正してほしいタグがあります。サイトのタイトルを変えましょう。35行目にある <title>クイズアプリ</title>
の部分を好きなタイトルに修正してください。
修正したら保存しましょう。保存は Ctrl+S / Cmd+S
などショートカットキーを使うようにしましょう。編集し終わったらこまめに保存しておくと、もし VSCode が落ちてしまったときなどに痛い目に合わずに済みます。
次に、Google Chrome で app.html
ファイルを開きます。エディタで修正したらブラウザを開き更新(再読み込み)する癖をつけてください。編集した部分が変わっていない場合は、VSCode側で保存するのを忘れているか、再読み込みしていない可能性があります。
タブに書いてある名前が変更できていれば成功です。
タブの名前を変えただけではあまり感動しないかもしれません。次は画面に表示されているクイズのタイトルと説明を修正しましょう。VSCodeに戻り、次のコードを探してください。
見つけたら、「クイズタイトル」の部分と「クイズの説明がはいります」の部分を、好きな言葉に変更してください。変更し終わったら必ず保存して、ブラウザで確認してみましょう。
3.3 で修正したプログラムをもう一度見てください。ここには3つのタグが出てきてます。
これらはすべてHTMLのタグです。中学校や高校の技術や情報の授業でやったことがある方もいらっしゃるかもしれません。基本的にはその当時やったものと変わっていないはずです。
しかし、div タグや h1 タグの中になにやらいろいろと書いてあります。class=""
の中に書かれているのが Bootstrap の命令とCSS の命令です。h1タグを例に見てみましょう。
ここでは、 text-center
と main-title
というクラスがつけられています。このうち、text-center
は Bootstrap の命令、 main-title
は CSS の命令です。
Bootstrap は本来であれば CSS で書かねばならない命令を事前にまとめてくれているフレームワークです。例えば text-center
をCSSで書くと次のようになります。
これをいちいちCSSで定義するのは面倒なので、Bootstrap は HTML の中に直接に書けるようにしてくれています。text-center のように一行の場合はまだかんたんですが、もっと複雑で長いプログラムを1つにまとめてくれている命令もあります。
では、 main-title
のほうはどうでしょうか。一見すると Bootstrap と同じように見えますが、これは自分で定義した命令になります。VSCodeで main.css を開いて、22行目を見てください。
main-titleという命令は、フォントサイズの変更と太さの変更によってできていることがわかります。このように、CSSではいくつかの命令のまとまりをHTMLのタグに適用していくことでデザインをしていきます。
それでは試しに、 font-size を大きくしてみましょう。好きなサイズに変えてみてください。
修正したら CSS ファイルを保存してブラウザを再読み込みしましょう。もし変わらなかった場合は、強制再読み込みをしてください。Shift+Cmd/Ctrl+R
を同時に押すと強制再読み込みされます。フォントサイズが変わっているでしょうか?
このように、Bootstrap で定義されている命令もあれば自分で定義することもできます。自分で定義をする場合には、 main.css に書き込んでください。
Bootstrap はCSSの様々な命令をまとめてくれているフレームワークですが、最も恩恵を受けるのがグリッドシステムです。グリッドシステムをつかえば、ボタンや画像、タイトルなどのパーツの配置がかんたんにある程度のクオリティを持ってすることができます。例えば、次のHTMLを実行するとこのようなレイアウトを作ることができます。
あるいは、このようなレイアウトも作ることができます。
Bootstrap のグリッドシステでは、画面全体を12分割したうちの何個分の領域を使うかによってパーツの幅を決めることができます。実際のアプリの画面とコードを見ながら理解していきましょう。
例えば、この画面では次のようなプログラムをしています。
2行目の <div></div>
で col-md-8
を設定しています。これが8個分の幅を使うという命令です。また、さらに offset-md-2
を設定することで、左右に2つ分の余白を設定しています。
左の余白2つ分 + 中央の表示領域8個分 + 右側の余白2つ分 を合計すると全体で12になります。これで8個分の領域を画面の中央に表示させることができるのです。
さらに、Bootstrap のグリッドシステムを使うことで、レスポンシブ対応をすることができます。最近ではスマートフォンでホームページを見ることが当たり前になりつつありますが、スマホの画面は基本的に縦長です。それに対して、コンピュータやタブレットでは横長で見ることが一般的でしょう。その際に、コンピュータを前提として作ってしまうとスマートフォンの表示にあっていなかったり、その逆もまた然りといったことが起こってしまいます。
それに対応するのがレスポンシブデザインです。レスポンシブ対応をしておけば、どんな画面サイズのデバイスで見ようと、ある程度きれいな形で表示してくれるようになります。
Bootstrap のグリッドシステムはとても優秀なので、どんどん使っていきましょう。基本的には次のような構成になっています。
基本的に container は1つのページにつき1つあればよいでしょう。row は1つのまとまりごとにつくるとよいです。
1つの row は12等分され、その中に含まれている col が指定する数によって幅は変動していきます。それでは、もし1つのrowに含まれている col の合計数が12を超えてしまった場合はどうなるでしょうか。アプリの画面を見ながら考えてみましょう。
index.html にはクイズの一覧が表示されていますが、それぞれの幅は col-md-3 で設定されています。このカラムを複数コピーすると、次の写真のように表示されます。
全体の個数が12を上回ると、下の段に追加されていくのがわかるかと思います。よって、一覧表示の場合どでは、1つのrowの中に複数のカラムを追加していくことが一般的です。
これでなんとなくグリッドシステムについて知ることができたでしょうか。さらに詳しく知りたい方は、公式ドキュメントを御覧ください。
https://getbootstrap.jp/docs/4.5/layout/grid/
なんとなくアプリの構造が解ってきたところで、早速アプリの機能を作っていきましょう。その際に、このテキストで紹介されているプログラムをコピペするのではなく、自分の手で入力すると力がついていきますので、プログラミングスキルを習得したい方は、ぜひ頑張って挑戦してみてください。
まずはHTMLとBootstrap を使ってアプリの見た目を完成させていきましょう。頭で理解するより前に手を動かして慣れることを目標にしましょう。
app.html の中に「問題数を表示する領域」と書かれている部分があります。その下に、次のプログラムを追加してください。
このように表示されれば成功です。
次に問題文を表示する領域を作りましょう。「問題文を表示する領域」と書かれている行の下に、次のプログラムを追加しましょう。
このプログラムの4行目のdivタグで指定している questionBox
と box-title
はmain.cssで定義しています。「問題」というテキストや枠線の色を変えるには、main.cssを編集してください。
※ 参考 main.css で定義されているCSS。すでに定義されているので書かない。
つづいて、クイズの選択肢を表示する領域を作りましょう。
<ol></ol>
タグで数字のリストを作っています。<li></li>
タグのclassについている my-3
は、上下に少しずつマージン(余白)を取るための Bootstrap 命令です。試しに my-3 をとってみるとすこし窮屈に見えるのがわかるかと思います。
今回つくるアプリは3択クイズなので、解凍ボタンを3つ作ります。次のコードを書き写してください。
CSSクラスの解説をします。aタグを見てください。
answer-btn
は main.css で定義されています。円と影を作っている CSS です。
answer-btn-bg-1
では、ボタンの色を設定しています。3つ同じにすると分かりづらいので、今回は bg-1 から bg-3 まで別々の色を指定しています。
#
から始まる6桁のアルファベットと数字の組み合わせは、カラーコードと呼ばれるもので、色を16進数で表したものになります。詳しく知りたい方はこちらのサイトを御覧ください。
さて、これでアプリの骨子は完成しました!ここまでお疲れさまでした。しかし、これだけではただ表示されているだけなので、ここから Vue.js を使って動きを作っていきます。g
app.html の下の方に <script></script>
タグに囲まれたプログラムがあります。この部分が JavaScript のプログラムです。事前にいくつか書いてありますが、一旦気にせず作っていきましょう。
Vue.js を理解するまえに、まずは JavaScript の基本的な構文を理解しましょう。以下では、ざっくりとした最低限度の解説しかしていません。さらに詳しく動画で知りたい方は、dotinstallで無料公開されているこちらの動画を見てください。
https://dotinstall.com/lessons/basic_javascript_v5
練習するためのファイルとして、javascript-practice.html
を用意しました。VSCodeでこのファイルを開き、<script></script>
の中にこれから下のプログラムを書き写していってください。
このあと出てくる console.log() は、ブラウザのコンソールに文字や数字などを出力するための命令です。Google Chrome で Windows の方は Ctrl+Shift+i を、macOSの方は Cmd+Option+i を押すと開発者ツールが開きます。さらに、下の画像で赤丸で囲まれている部分(Console)をクリックするとコンソールが開きます。
変数(へんすう)をとは文字通り「変わる数」のことです。ただし数と言っているものの、文字やオブジェクトなどいろいろなものを格納することができます。まずは、JavaScript で変数を定義する方法を紹介します。
文字列には必ず "ダブルクォーテーション" をつけましょう。数字にはいりません。逆に "10" と表現すると、文字列として認識されます。
変数は変わる数なので、一度定義した変数の中身を変えることができます。次のコードを実行すると、次のような結果になります。
例えば、クイズの正解数を保存する変数を考えてみましょう。始めは正解数は0なので、次のように定義できます。
正解したときに1ずつ増やすためには次のように増やします。
変数には真偽値(true / false)を格納することもできます。真偽値は true または false のうちどちらかしかありません。例えば、質問に正解しているかどうかを判定するプログラムは次のように書きます。
プログラミングの世界で「○○かどうか」といった条件を保存する変数名は is を始めにつけることが多いです。
変数は変わる数でしたが、不必要なところで変えられてしまうと困るような値を保存することもあります。例えば、ユーザ名など一度定義したらそれ以上変えたくありません。そこで登場するのが定数です。 JavaScript では次のように定数を定義します。
変数と定数は必要なときに使い分けると良いでしょう。基本的に定義したあとから変えたいものは変数、一度定義したらそれ以上変えないもの(参照だけするもの)は定数として定義することが一般的です。
変数と定数はどちらも1つの値しか保存することができません。しかし、例えば学級の子どもたちの名前を保存したいときにはどうすればよいでしょう。
そこで登場するのが配列です。配列は、次のように定義します。
配列を使えばこのように複数の要素を1つの変数(または定数)に保存することができます。
配列に保存されたデータは次のように使います。
配列は追加された順に0始まりで数字(これを添字といいます)が付きます。1からではないことに注意してください。
たとえば、上の classKids 配列で Yuto さんのデータを取得したいときには次のように書きます。
2.4.4で紹介した配列はただ名前を保存するだけの配列でした。しかし、これよりもっと複雑な情報(例えば、それぞれの出身地や性別、メールアドレスなど)を1つの配列で管理したい場合どうすればいいでしょう。
JavaScript ではオブジェクトと呼ばれる配列に似たものが用意されています。次のコードを見てください。
taroオブジェクトに保存されているデータを取得する場合には次のようなプログラムを書きます。
さらに、オブジェクトを配列に格納することもできます。次のコードを見てください。
このオブジェクトのデータを参照するためには次のように書きます。
今回作るクイズアプリでは、問題文をこのように保存しています。具体的な使い方については後ほど確認しますので、ここではさらっと確認しておきましょう。
ここまではデータの保存について解説してきました。次に変数の使い方を紹介します。
例えば、得点に応じて表示する言葉を変えるプログラムは次のように書きます。
if の中には条件式が入ります。条件式には次のようなものがあります。
数学では「 = 」は左辺と右辺が等しいことを表していますが、プログラミングの世界では、変数の中に代入する記号として使われています。その代わり、「 == 」と書いて、等しいかどうかを判別しています。
if文を使えば、クイズの答えがあっているかどうかを判定することもできます。
ちなみに、細かい話ですが次のif文の結果は false になります。
これは、「新宿」と「区」の間にスペースが入っているかどうかが違うだけです。しかし、プログラミングではこの2つを別物と解釈します。実際にプログラムで使うときにはこのあたりに注意してください。
プログラミングでは「繰り返し」を使うことによって、同じような作業をかんたんにすることができます。例えば、次の上のプログラムと下のプログラムは同じ結果になります。
変数 i は1つの繰り返し処理が終わると1つずつ増えていきます。iに0以外の数を設定すれば、その数からループが始まります。
for文は配列と組み合わせるととても便利に使うことができます。例えば次の prefectures 配列の中身を順番に表示するプログラムはこのように書くことができます。
今回つくっているアプリでも別の書き方(Vue.jsの書き方)ではありますが、この繰り返しの概念を使います。覚えておいてください。
関数とは、複数の処理をまとめて1つにしてくれるものです。一般的には次のように記述します。
これだけだとおもしろくありませんが、引数(ひきすう)という機能を使うとつぎのような処理をすることができます。
引数は変数と似たようなもので、その関数の中だけで使えます。引数はカンマで区切ることで複数使うこともできますし、配列を入れることもできます。このあたりは使いながら慣れていきましょう。
ここまで JavaScript の書き方について紹介してきました。ざっと紹介したのでまだ理解できていないところもあるかもしれませんが、まずは簡単な理解で構いません。何度も繰り返してやることで自然と覚えていきます。
さて、ここまでやってようやく Vue.js にたどり着きました。Vue.js は何度も紹介している通り、JavaScript のフレームワークです。よって、生の JavaScript とは一部書き方が異なります。その違いだけ注意してください。
一般的な Vue.js の構成は次のようになっています。
先に学んだ JavaScript の記法と少し異なる点がいくつかあります。まず、アプリ全体でつかう 変数は var
で宣言するのではなく、 data:{}
の中に変数名だけ定義して、=ではなく:を使います。Vue.js で変数を定義するには次のようにします。
また、関数を定義するときは methods:{}
の中で function を使わずに次のように定義します。
app.html には予め Vue.js が次のようにかかれています。
すでに書かれている部分については深く理解する必要はありません。まずはここにこう書くんだなくらいのことを理解してくれればOKです。
まずは、問題を管理するオブジェクトを作成しましょう。app.htmlにはすでに問題文の一部が定義されています。
1つ1つのオブジェクトに問題のタイトル,ヒント,答えの選択肢,正解の番号,説明を保存しています。まずは、0番目のオブジェクトをコピーして、0を1に変えてタイトルなどの情報も変更しましょう。
最終的に問題を7個つくりました。ここまで作ってみてください。
これで問題文のデータを作ることができました。次は問題文を表示するプログラムを作ります。
問題文を表示するには、HTMLの部分に Vue.js を適用していきます。問題文を表示する領域にある <p></p>
の中身を次のように編集していください。
Vue.js では、 {{ }}
のように中括弧を2つ並べたところに変数を入力すると、変数に保存されている中身を表示してくれます。このカッコのことをマスタッシュといいます。さて、ここではどのような言葉を表示しているのでしょうか。
まず、 questions
というのは先程作った問題文のオブジェクトが保存されている配列です。配列の要素を取り出すには 4.2.4 で学習したとおり、数字(添字)が必要となります。今回の場合、必要となる数字は現在の問題番号です。ここでは、 currentQuestionNumber
という変数で問題番号を管理しています。 questions[currentQuestionNumber]
とすることで、個々の問題オブジェクトにたどり着きました。その中の title
にアクセスしたいため、最終的には questions[currentQuestionNumber].title
となります。
ここまでできたら保存してブラウザを再読み込みしてみましょう。一問目の問題文が表示されているでしょうか。
次に、回答の選択肢を表示しましょう。「回答の選択肢を表示する」領域を次のように書き換えてください。
>li> </li>
タグに注目してください。ここに v-for
という命令が出てきています。Vue.js を使ってHTMLの中で for 文 を使うためにはこのように記述します。
この命令は他の言語で言う foreach 文に近い構造をしています。このfor文は questions 配列の中に保存されている問題文オブジェクトに含まれている answer 配列の個数だけ繰り返されます。そして、1回のループごとに answer という疑似変数の中に answers の要素が代入されています。上のプログラムの5行目で {{answer}}
と書いていますが、これは answers の中身の1つ1つだと思ってください。
この概念は少し難しいので、何度か繰り返しやってみるといいかと思います。
ここまでできたら保存し、ブラウザをリロードしてください。回答の選択肢が表示されているでしょうか。
問題文を表示する領域を次のように書き換えてください。
保存してブラウザを再読み込みしても、現在の問題番号が表示されていないと思います。現在の問題番号を表示するために使っているのは getCurrentQuestionNumber()
という関数です。この関数は定義はされているものの、中身がまだ書かれていません。 app.html の下の方にある Vue.js の methods の中に getCurrentQuestionNumber() 関数がありますので、次のように修正してください。
currentQuestionNumber
で管理している問題番号は、配列で使う都合上0から始まっています。しかし、「第0問」とは言わないので1足した数を表示するようにしています。関数では return という機能を使って、関数の中で行われた計算結果を外に出す仕組みがあります。これについても、とりあえずこのようなものがあるということを知っておけば十分です。
現在の表示されているボタンはクリックされてもなにもおこりません。ボタンを動かすためには次のようにプログラムを改造します。
それぞれのaタグの要素に @click="answerCheck(0)
を指定しました。@click=
はVue.js の書き方で、HTML要素から Vue.js の関数を呼び出すときに使われます。これは、このaタグをクリックしたときにanswerCheckという関数を実行してくださいという命令です。では、answerCheckという関数はどうなっているのでしょうか。現時点ではまだ定義されているだけで中身がないので、次のように書き加えてください。
answerCheck関数はユーザが選択した問題番号が引数になっています。それが userChoiceNumber
です。この引数が問題を保存している questions 配列の問題番号番目で定義されている答え(answerNum)と同じかどうかを if文 でチェックしています。もし正しかったら、答えがあっているかを管理している変数 isCorrect
をtrueにして、正解数を管理している変数 correctAnswerNum
を1ずつ増やしています。
逆に不正解だった場合には、isCorrect
変数の値をfalseにしています。
先程書いたプログラムの最後に「結果を表示するモーダルを表示する」という部分がありました。モーダルとは、ポップアップされて出てくるウィンドウのことで、このアプリでは正解/不正解の表記に使っています。
正解したときと不正解のときによって表示される内容を変えたいので、app.html の「答えを表示するモーダル」の下にかかれているプログラムを次のように修正してください。ソースコードは長いですが、修正する箇所はそこまで多くありません。どこが変わっているかじっくり見比べてください。
まず、上のプログラム5行目にあるh5タグで、問題番号を表示するようにしています。
次に、23行目の正解したときの説明に答えを表示しています。
不正解だったときも同様です。29行目と23行目はほぼ同じですが文末表現を変えています。
最後に、次の問題にすすめるためのボタンに関数を適用させています。
これで回答のチェックができるようになりました!完成まであと少しです!
すべてのクイズを解き終わったあとに表示するモーダルを作りましょう。
修正したのは次の点です。
これでアプリ自体は完成です!お疲れさまでした。