見出し画像

Nuxt.jsでクイズページを作る その1

私の所属している墨田謎製作所でイベントをやったときに、QRコードからWebを開いて答えを入力する部分を作ったのですが、よくありがちなのに意外と情報がなかったので、作り方を書いておきます。

今回はNuxt.jsで作りましたが、Vue.jsもそんなにやったことがないので、もし情報が間違っているようでしたらご指摘ください。

使用した環境

・macOS Catalina
・Nuxt.js
・nuxt-buefy
・Firebase Hosting
・VS Code

なぜNuxt.js

クイズという性質上、Webのソースに答えが書いてあるようではいけませんね。
JavaScriptで答えを隠してクイズを作るのはなかなか面倒です。
だからといってクイズ1問のためにサーバーを立ててphpだのRubyだので作るのは、ちょっと大変です。

Vue.jsにルーティングの機能がついているNuxt.jsだと、後述するように1問ごとにURLを分けたページも簡単に作れますし、アプリサーバーを立てる必要もありません。
今回はホスティングにFirebaseを使いましたので、Webサーバーもすぐに作れました。

Nuxt.jsのインストール

Nuxt.jsのインストールについては、公式ページにわかりやすく書いてあります。
https://ja.nuxtjs.org/guide/installation/

今回のプロジェクトでは、以下のような設定で作成しました。

% npx create-nuxt-app nuxt-quiz-sample1

create-nuxt-app v2.11.1Generating Nuxt.js project in nuxt-quiz-sample1
? Project name nuxt-quiz-sample1
? Project description My supreme Nuxt.js project
? Author name Kunihiko Karasawa
? Choose the package manager Npm
? Choose UI framework Buefy
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools jsconfig.json (Recommended for VS Code)


Nuxt.jsでは、pagesフォルダに置いたvue.jsファイルを自動的にページとして認識してくれます。
例えば、aaa.vue というファイルを作ったとすると、
https://your_toppage_com/aaa
というURLでアクセスできます。

今回はクイズのページはQRコードを見つけないとアクセスできないようにしたので、推測されにくい名前のページを作りました。

ページの作成

それでは pagesフォルダに置いたクイズのページを作成していきます。

ページでは3つの変数を使用します。

data () {
   return {
     keywords: ['たこ', 'タコ', 'tako'],
     clear: false,
     badanswer: false
   }
 },

keywords - 正解のキーワードのリスト
clear - 正解したかどうかのフラグ
badanswer - 不正解だったかどうかのフラグ

これらの変数は保存していないので、ページをリロードすると変数がクリアされてしまいます。
変数を保存して、例えば1問目に正解していないと2問目を開けないなどとする方法は次回書く予定です。

問題の入力欄やOKボタンはBuefyのオブジェクトを利用しました。
Buefy
https://buefy.org/

<b-field>
 <b-input v-model="answer" />
</b-field>
<b-button @click="check(answer)">
 OK
</b-button>

OKボタンを押すと、入力フィールドの値が check() 関数に送られます。

methods: {
   check (answer) {
     let isCorrect = false
     for (const keyword of this.keywords) {
       if (keyword === answer.toLowerCase()) {
         isCorrect = true
         this.clear = true
         break
       }
     }
     if (isCorrect === false) {
       this.badanswer = true
     }
   }
 }

check()関数では、入力された値がkeywordsのうちのどれかと同じだったら clear を trueに、合ってなければ badanswer を true にします。
変数が変化すると、templateの部分が自動的に再描画されます。

ユーザーがどんな答えを入力しても大丈夫なように、キーワードはカタカナ、ひらがな、漢字など思いつく正解キーワードを複数用意しておくといいと思います。

英語の場合、入力された値は小文字に変換して比較するので、キーワードに小文字を書いておくといろいろなケースに対応できます。

テンプレート

<template v-if="clear === false">
 <h2 v-show="badanswer">
 --- 不正解の場合の表示 ---
 </h2>
 --- 問題文と入力欄 ---
</template>
<template v-else>
--- 正解の場合の表示 ---
</template>

templateでは、 v-if v-else 文を使って、 clear 変数の値によって表示を振り分けています。
答えが間違っていた場合は正解していないので clear は false ですが、badanswer が true になっているはずですので、v-show を使って問題文の上に「不正解」の文字を出しています。

Firebaseへのデプロイ

今回はWebサーバーとして Firebase Hostingを利用しました。

Firebase Hostingの設定方法はこちら
https://firebase.google.com/docs/hosting/quickstart?hl=ja

Nuxt.jsでは、公開用のファイルは dist フォルダに生成されるので、firebase.jsonの設定を以下のようにします。

{
 "hosting": {
   "public": "dist",
   "ignore": [
     "firebase.json",
     "**/.*",
     "**/node_modules/**"
   ]
 }
}

Nuxt.jsをビルドして、Firebaseにアップロードしてみます。

% npm run build
% npm run generate
% firebase deploy --only hosting


サンプルプロジェクトはGitHubにおきました。
https://github.com/krsw9215/nuxt-quiz-sample1

クイズのデモはこちらからどうぞ。
(問題文はべスパ☆くまメロのもんちゃんの投稿を勝手に拝借しました)
https://nuxt-quiz-sample1.web.app/bghj86gd/

この記事が気に入ったらサポートをしてみませんか?