Vueで複数画面構成を作る router設定#
通常、Webアプリケーションはいろいろな機能を持っており、機能によっては画面を複数にして構成します。 たとえば、アンケートアプリだと、 * アンケートを回答する画面 * アンケートを確認する画面 などです。
ここでは、アンケートを回答する画面とアンケートを確認する画面をVueのRouterという機能を使って構成します。
前提#
アンケートアプリをここまで作成してください。
Routerの設定#
Routerは、URLのパスに画面を割り当てることができます。 URLは
{プロトコル}://{ドメイン名(サーバ名)}/{パス}
のような形式で出来上がっています。 早速、パスにより画面が切り替わるようにしていきます。
まずは Vue Routerをインストールします。 ターミナルのnpmディレクトリにて、以下のコマンドを実行します。
npm install vue-router
パスに割り当てるコンポーネントを作成します。今回はアンケートの結果を一覧で表示するコンポーネントを作成します。
src/front/components/EnqueteResultList.vue を以下の内容で作成してください。
<template>
<div>
<h1>アンケート回答一覧</h1>
<table>
<tr>
<th>点数</th>
<th>ご意見・ご要望</th>
<th>メールアドレス</th>
</tr>
<tr v-for="enquete in enquetes" :key="enquete.id">
<td>{{enquete.point}}</td>
<td>{{enquete.message}}</td>
<td>{{enquete.mail}}</td>
</tr>
</table>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import axios from "axios";
export default Vue.extend({
data() {
return {
enquetes: [],
};
},
async created() {
const response = await axios.get("/api/enquetes");
this.enquetes = response.data;
},
});
</script>
サーバ側のAPIを作成します。 src/backend/controllers/enquete.ts を編集、5行追加します。
import express, { Router } from 'express'
import { getRepository } from 'typeorm'
import Enquete from '../models/Enquete'
var router: Router = express.Router();
router.post('/', async function (req, res) {
const enquete = req.body;
const EnqueteRepository = getRepository(Enquete);
await EnqueteRepository.save(enquete);
res.send(enquete);
});
//ここから
router.get('/', async function (req, res) {
const EnqueteRepository = getRepository(Enquete);
const enquetes = await EnqueteRepository.find();
res.send(enquetes);
});
//ここまで追加
export default router;
これで、EnqueteResultListコンポーネントが動くようになりました。
このコンポーネントを パス /enquete/list に割り当てます。
次に、src/front/components/App.vue にrouteの設定をします。
<template>
<div>
<router-view /><!-- post-enquete を router-view に変更します。 -->
</div>
</template>
<script lang="ts">
import Vue from "vue";
import VueRouter from "vue-router";//この行を追加
import PostEnquete from "./PostEnquete.vue";
import EnqueteResultList from "./EnqueteResultList.vue";//この行を追加
//ここから
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: PostEnquete },
{ path: '/enquete/list', component: EnqueteResultList }
]
})
//ここまで追加
Vue.use(VueRouter);//この行を追加
export default Vue.extend({
router //この行を追加
//components: { PostEnquete }, // この行を消します。
});
</script>
パスにコンポーネントを割り当てるためには、 templateタグの中で差し替えたい場所をrouter-viewタグにして、 パスとコンポーネントの関連をVueRouterに設定します。
最後に、サーバでは、API以外のどのパスにリクエストされても、index.htmlを返却するようにします。 src/backend/index.tsに3行追加します。
import express from 'express'
import messageController from './controllers/message'
import enqueteController from './controllers/enquete'
import { createConnection } from 'typeorm'
import Enquete from './models/Enquete'
const app: express.Express = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use("/messages", messageController)
app.use("/api/enquetes", enqueteController)
app.use("/", express.static(__dirname + "/public"))
//ここから
app.get('*', (req, res) => {
res.status(200).sendFile(__dirname + "/public/index.html");
});
//ここまで追加
!async function initialize() {
await createConnection({
type: "postgres",
url: process.env.DATABASE_URL || "postgres://postgres:postgres@localhost:5432/postgres",
synchronize: true,
entities: [
Enquete,
],
extra: {
ssl: (!!process.env.DATABASE_SSL) ? {
rejectUnauthorized: false,
} : false,
}
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log("ポート" + port + "番で起動しました!")
})
}()
更に、index.htmlがどのパスでアクセスされてもbundle.jsが読めるように修正を加えます。 src/front/public/index.html を一行(一文字)修正します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My App</title>
</head>
<body>
<div id="app"></div>
<script src="/js/bundle.js"></script><!-- パスの前の . を削除。絶対パスで読めるようにする。-->
</body>
</html>
これにより、ブラウザでhttp://localhost:3000/enquete/list を入力しても、index.htmlが表示されるようになりました。 index.htmlによって読み込まれたVueが、パスを見て、ブラウザ上でアンケート一覧を表示します。
これで、複数画面構成を作成することができるようになりました。 ただ、これではアンケート結果がみんなから丸見えですね。次はアンケート結果のページはログインしていないと見れないようにします。