Nuxt.jsで選択式クイズアプリを作ってみた

  • プロダクション

経緯

トライベックでは定期的にLearning.Styleという業務研修を行っており、各部が他の部に向けて講義を行っています。
私が所属する部ではHTML,CSS,JSについての講義を行っているのですが、
ただ聞いてもらうだけでなくハンズオン形式で出来たら頭に入ってきやすい、
選択式クイズアプリをNuxt.jsを用いて作ってみました。

利用した技術

■Nuxt.js

vue.jsのフレームワークです。
ルーティングを管理行える「Vue-Router」や状態管理を簡単に行える「Vuex」といったパッケージが最初から入っているため、開発が楽に出来ます。
静的ファイルの作成も出来るので、今回は出力した静的ファイルを社内の共有サーバーに設置して、講義を受けている人に見てもらうようにしました。

製作時間

5時間くらい

完成品

作成した画面数は3つになります。

トップ画面

トップ画面_L.png

初めに表示される画面。問題集一覧をJSONから読み込み、画面に表示する。
問題集を選択し、【問題を解く】ボタンを押下すると、対象の問題集の情報を読み込み問題解答画面に遷移する。

問題解答画面

問題解答画面_L.png

選択式の問題が出題される画面。答えだと思う選択肢を選び【解答】ボタンを押下。
誤ってボタンを押してしまったときのために前の問題に戻ることも可能。
設定ファイルをいじることで、問題や選択肢の順番をランダムにすることも可能。
全ての問題に解答すると解答結果画面に遷移する。

解答結果画面

解答結果画面_L.png

各問題について答え合わせが出来る画面。
間違った場合は自分の選んだ項目が赤色で表示され、正解の項目が緑で表示される。
【終了】ボタン押下でトップ画面に遷移する。

ファイル構成

・
├── assets
├── components
│   ├── questions
│   │   └── qInfo.vue    問題のコンポーネント(問題文+選択肢)
│   ├── questions.vue    問題解答画面のコンポーネント
│   ├── result.vue       解答結果画面のコンポーネント
│  └── top.vue          トップ画面のコンポーネント
├── dlist
├── layouts
│    └── default.vue    ページのレイアウト
├── middleware
├── pages
│    └── index.vue         本システムのメインページ
├── plugins
│    └── commonFunc.vue    共通関数を定義
├── static
│    └── json
│         ├── question_css.json     cssに関する問題集
│         ├── question_html.json    htmlに関する問題集
│         ├── question_js.json      jsに関する問題集
│         ├── question_other.json   CMSや通信に関する問題集
│         └── settings.json         本システムの設定ファイル
└── store
└── common.js    コンポーネント間の値の受け渡しを行う

■assets

共通のCSS(SCSS)や画像ファイルなどを格納。

■components

コンポーネントファイルを格納。

■layouts

ページの外観を設定できる。共通ヘッダー・フッターを設定できる。

■middleware

ページが表示される前に実行したい処理などを定義する。

■pages

アプリケーションのビュー及びルーティングファイルを格納。

■plugins

インスタンス化する前に実行したい JavaScript プラグインを格納。

■static

ここに置かれたファイルは直接サーバのルートに配置される。
JSONファイルは誰でも簡単に修正できるようにこのディレクトリ内に配置。

■store

vuexストアのファイルを格納

工夫した点

  • 解答ページを作成することで、答え合わせを行えるようにした。何問正解したが分かるようになっており、正解の選択肢もハイライトにして分かりやすくしている。
  • JSON形式の設定ファイルを作成することで、ソースを修正しなくてもタイトルの修正や問題の差し替え、問題や選択肢のランダム機能のON,OFFを設定できるようにした。(※1)

(※1)下記のようなJSONファイルを"static/json/"配下に設置

setting.json

{
    "title": "web問題集",
    "btnName": "問題を解く",
    "questionPaths":[
        {
            "filePath": "./json/question_html.json",
            "title": "HTMLの問題"
        },
        {
            "filePath": "./json/question_css.json",
            "title": "CSSの問題"
        },
        {
            "filePath": "./json/question_js.json",
            "title": "JSの問題"
        },
        {
            "filePath": "./json/question_other.json",
            "title": "Webその他問題"
        }
    ],
    "randam": true,
    "choiceRandam": true
}

title→システムのタイトル
btnName→トップページのボタン名
questionPaths.filePath→問題集のパス
questionPaths.title→問題集のタイトル
randam→問題のランダムのON(true),OFF(false)
choiceRandam→選択肢のランダムのON(true),OFF(false)

問題ファイルのJSONは下記のようなフォーマットになっている。
下記はHTMLの問題集(static/json/question_html.json)

{
    "questionList": [
        {
            "no": 1,
            "question": "段落を指定するためのタグは次のうちどれか。",
            "choice": [
                "p", "span", "pre", "div"
            ],
            "answer": "p" 
        },
        {
            "no": 2,
            "question": "リンクの出発点と到達点を指定するために使われるタグは次のうちどれか。",
            "choice": [
                "p", "span", "a", "table"
            ],
            "answer": "a" 
        },
        ...
    ]
}

no→問題のインデックス
question→問題の内容
choice→問題の選択肢
answer→問題の解答

新しい問題を作成したい時は、先に問題ファイルの作成し、設定ファイル(setting.json)にパスを記述してあげるだけよい。

改良案

■問題JSONファイルのフォーマット変更

現状は選択した選択肢と"answer"の値の完全一致で成否を判定しているが、
選択肢にもIDを振り、answerにはそのIDを設定するように改良。

■記述形式にも対応

現在は選択式の問題しか作成できないため記述式の問題も作れるように改良。
問題ファイルに問題形式のkeyを追加(選択式 or 記述式)。

さいごに

今回は作ったシステムの大まかな概要を説明しましたが、次のコラムでは本システムのソースコードを交えながら各コンポーネントの説明が出来ればと思います。

この記事の執筆者

Y.M

トライベック・プロフェッショナルサービス株式会社

この記事に関するご相談やご質問など、お気軽にお問い合わせください。

お問い合わせ

タグ一覧