Skip to content

Vueで画面を作ってみる。#

VueReact,Angularに並ぶ3大フロントエンドフレームワークといえます。

Vueの役目はHTMLをユーザの操作に応じて適切に書き換えることです。

ここでは、Vueを使ってアンケートアプリの画面を作っていきます。

前提#

TypeScriptプロジェクトの作成及びVueの設定を行ってください。 ターミナル(もしくはコマンドプロンプト。以下ターミナルに寄せます。)を開き、プロジェクトのルートディレクトリにcd しておいてください。

自動再起動、起動。#

アプリケーションを更新した際に、更新が自動的に反映されるようにします。 これまで、サーバサイドと画面それぞれは自動再起動されるようになっているため、両方ともが1コマンドで再起動されるようにします。

サーバサイドと画面の自動再起動を同時に実行してくれるツールをインストールします。

npm install -D npm-run-all

次に、package.jsonの以下の場所に、

  //省略
  "scripts": {
    "watch:backend": "tsc-watch --onSuccess \"node dist/index.js\"",
    "watch:front": "webpack --config webpack.front.config.js --watch --mode development",
  //省略

一行追加します。

  //省略
  "scripts": {
    "watch": "run-p watch:*",
    "watch:backend": "tsc-watch --onSuccess \"node dist/index.js\"",
    "watch:front": "webpack --config webpack.front.config.js --watch --mode development",
  //省略

最後のカンマを忘れないでください。 run-p で並行起動、watch:* でwatch:から始まるすべてのscripts中のタスクを実行してくれます。

これで自動再起動の設定が完成です。

後はターミナルで、以下を実行すれば、自動再起動でサーバが起動します!

npm run watch

HTMLをサーバ経由で取得できるようにする#

HTMLをサーバ経由で公開可能にします。 src/backend/index.ts に一行追加します。

import express from 'express'
import messageController from './controllers/message'

const app: express.Express = express()

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.use("/messages", messageController)
app.use("/", express.static(__dirname + "/public"))//この行を追加します。

// 3000番ポートでAPIサーバ起動
app.listen(3000, () => {
    console.log('ポート3000番で起動しましたよ!')
})

Vueでアンケート画面を作成する。#

アンケート入力フォームを作成します。 src/front/components/PostEnquete.vue を以下の内容で作成してください。

<template>
  <div>
    <h1>{{title}}</h1>
      <p>{{description}}</p>
    <div v-if="!posted"><!-- 入力エリア ここから -->
      <div>
        <input type="radio" id="5" value="5" v-model="enquete.point"><label for="5">5点</label>
        <input type="radio" id="4" value="4" v-model="enquete.point"><label for="4">4点</label>
        <input type="radio" id="3" value="3" v-model="enquete.point"><label for="3">3点</label>
        <input type="radio" id="2" value="2" v-model="enquete.point"><label for="2">2点</label>
        <input type="radio" id="1" value="1" v-model="enquete.point"><label for="1">1点</label>
      </div>
      <div>
        <p>ご意見・ご要望</p>
        <textarea v-model="enquete.message"></textarea>
      </div>
      <div>
        <p>メールアドレス</p>
        <input type="mail" v-model="enquete.mail" />
      </div>
      <div>
        <button @click="sendMessage()">アンケート送信</button>
      </div>
    </div><!-- 入力エリア ここまで-->
    <div v-else><!-- 結果エリア ここから -->
      <div>
        点数{{enquete.point}}      </div>
      <div>
        <p>ご意見・ご要望</p>
        <p>{{enquete.message}}</p>
      </div>
      <div>
        <p>メールアドレス</p>
        <p>{{enquete.mail}}</p>
      </div>
    </div><!-- 結果エリア ここまで -->
  </div>
</template>
<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  data() {
    return {
      title: "アンケート",
      description: "良かったですか?5点(高い) から 1点(低い) で点数をつけてください。",
      enquete: {},
      posted: false
    };
  },
  methods: {
      sendMessage(){
        this.description = "アンケート送信をありがとうございました。";
        this.posted = true;
      }
  }
});
</script>

までが、画像表示を行う部分です。

が処理を書くところです。 画面表示中のv-model=""の""の中、および{{}}の中が、 処理を書くところのdata(){return {}}の中身と名前で関連付けられています。 enquete.pointや、enquete.message、enquete.mailが入力されて、処理するところで使うことができます。

画面表示中の@click="sendMessage"と書いてあるので、ボタンが押されると、処理のsendMessage()が呼び出されます。 処理でthis.postedにtrueを入れているので、ボタンを押すと入力エリアが非表示に、結果エリアが表示されるようになります。 本来、ここで、サーバにアンケート結果を送信したりするのですが、ここでは画面を動かすだけにします。

Enqueteコンポーネントを画面表示するようにします。

src/front/components/App.vue を以下のように修正します。

<template>
  <div>
    <post-enquete/> <!-- PostEnqueteコンポーネントを使っています。 -->
  </div>
</template>
<script lang="ts">
import Vue from "vue";
import PostEnquete from "./PostEnquete.vue" // PostEnquete.vueを読み込んでいます。

export default Vue.extend({
    components:{PostEnquete} // PostEnqueteを画面で使えるようにしています。
});
</script>

これでVueアプリの作成が完了しました!

http://localhost:3000にブラウザでアクセスしてみましょう!

入力欄 値を入力して、アンケート送信ボタンを押してください。 アンケート表示

これでVueでアンケート入力画面を作ることができました。

次はアンケートをデータベースに登録します。