こんにちは。KOUKIです。
前回に引き続き、ユーザー認証アプリの実装を行います。本記事は、主にフロントエンドで以下の処理について書きます。
1. ナビゲーションバーの作成
2. Registerページの作成
作業を始める前に、コンテナを起動しておきましょう。
1 2 |
// コンテナの起動 docker-compose up |
コンテナを立ち上げたら、「localhost:8080」にアクセスしてみましょう。

<目次>
前回
ファイル準備
開発に必要なファイルを作成します。
1 2 3 4 5 6 7 8 9 |
// uiフォルダ配下で以下を作成 mkdir src/pages touch src/pages/Login.vue touch src/pages/Register.vue touch src/pages/Home.vue touch src/pages/Forgot.vue touch src/pages/Reset.vue touch src/components/Nav.vue touch .eslintrc.js |
BootstrapCDNの導入
ページを簡単に作成するために、CSSのフレームワークであるBootstrapを導入します。ExamplesにBootstrapで何ができるかサンプルがあります。
BootstrapCDNから次のコードをコピーしてください。
1 2 |
// BootstrapCDN <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> |
これを、ui/public/index.htmlのhead要素内に記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!-- index.html --> <!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <!-- BootstrapCDN --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> ... </body> </html> |
これで、Bootstrapが使えるようになります。
ナビゲーションバーの作成
最初にナビゲーションバーを作成しましょう。BootstrapのNavbarを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Nav.vue <template> <nav class="navbar navbar-expand-md navbar-dark bg-dark"> <ul class="navbar-nav mr-auto"> <li class="nav-item"> <router-link to="/" class="nav-link">Home</router-link> </li> </ul> <ul class="navbar-nav my-2 my-lg-0"> <li class="nav-item"> <router-link to="/login" class="nav-link">Login</router-link> </li> <li class="nav-item"> <router-link to="/register" class="nav-link">Register</router-link> </li> </ul> </nav> </template> <script> export default { name: "Nav" } </script> |
router-linkは、Vue Routerの機能の一つです。
Vue Routerの機能は色々ありますが、ここでは各ページへのダイレクトリンクを貼っています。
Home, Login、Register.vueのそれぞれに以下の処理を実装してください。
1 2 3 4 5 6 7 8 9 10 11 12 |
// Home.vue <template> Home </template> <script> export default { name: "Home" } </script> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Login.vue <template> Login </template> <script> export default { name: "Login" } </script> <style> </style> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Register.vue <template> Register </template> <script> export default { name: "Register" } </script> <style> </style> |
これらをrouter/index.jsから呼び出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// router/index.js import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import Home from '../pages/Home.vue' import Login from '../pages/Login.vue' import Register from '../pages/Register.vue' const routes: Array<RouteRecordRaw> = [ { path: '/', component: Home}, { path: '/login', component: Login}, { path: '/register', component: Register}, ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) export default router |
そして、App.vueJSでは、先ほど実装したNavを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// App.vue <template> <Nav /> <router-view /> </template> <script> import Nav from "@/components/Nav" export default { components: { Nav } } </script> |
router-viewでVue Routerの機能が使えるようになるので、忘れないようにしましょう。
ここまで実装すると、ヘッダが表示され、リンクを経由して各々のページに遷移できるようになります。
Registerの作成
次は、Registerを作成します。
ページの作成
最初に、ページを作成しましょう。Bootstrapの力を借ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// Register.vue <template> <main class="form-register"> <form @submit.prevent="submit"> <h1 class="h3 mb-3 fw-normal">Please Register</h1> <input v-model="firstName" class="form-control" placeholder="First Name" required> <input v-model="lastName" class="form-control" placeholder="Last Name" required> <input v-model="email" type="email" class="form-control" placeholder="Email" required> <input v-model="password" type="password" class="form-control" placeholder="Password" required> <input v-model="passwordConfirm" type="password" class="form-control" placeholder="Password Confirm" required> <button class="w-100 btn btn-lg btn-primary" type="submit">Submit</button> </form> </main> </template> <script>...</script> <style> .form-register { width: 100%; max-width: 330px; padding: 15px; margin: auto; } .form-register .form-control { position: relative; box-sizing: border-box; height: auto; padding: 10px; font-size: 16px; } .form-register .form-control:focus { z-index: 2; } .form-register input[type="email"] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .form-register input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; } </style> |
v-modelは、フォーム入力バインディングと呼ばれるものです。フォームに入力した値が、変数(firstNameなど)に直接代入されます。

Submit処理の実装
次は、Submitボタンが押下された時の処理を書きます。
axiosが必要なので、ui配下で以下のコマンドを実行してください。
1 |
npm i axios |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<script> import { ref } from 'vue' import axios from 'axios' import { useRouter } from 'vue-router' export default { name: "Register", setup() { // v-modelからフォームに入力された値を格納 const firstName = ref(''); const lastName = ref(''); const email = ref(''); const password = ref(''); const passwordConfirm = ref(''); const router = useRouter() const submit = async () => { // Register apiへPOSTリクエスト await axios.post('register', { first_name: firstName.value, last_name: lastName.value, email: email.value, password: password.value, password_confirm: passwordConfirm.value, }) // ログイン画面に戻る await router.push('/login') } return { firstName, lastName, email, password, passwordConfirm, submit } } } </script> |
axios.postで、apiへリクエストを飛ばします。main.tsにベースとなるURLを定義しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 |
// main.ts import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import axios from 'axios' axios.defaults.baseURL = 'http://localhost:80/api/' // これ axios.defaults.withCredentials = true createApp(App).use(store).use(router).mount('#app') |
この様にすると「http://localhost:80/api/register」へリクエストを飛ばせるようになります。
注意:camel caseエラー
筆者の環境だとcamel caseエラーが表示されました。
1 2 |
/app/src/pages/Register.vue 59:9 error Identifier 'first_name' is not in camel case |

このエラーは、.eslintrc.jsに以下の設定を行うことで回避しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
module.exports = { root: true, env: { node: true }, extends: [ 'plugin:vue/vue3-essential', 'eslint:recommended', '@vue/typescript/recommended' ], parserOptions: { ecmaVersion: 2020 }, rules: { "@typescript-eslint/camelcase": "off" } }; |
この設定を行ったらコンテナを立ち上げ直してください。
動作確認
Registerページからユーザー情報を登録してみましょう。

リクエストが成功したので、ログインページに飛びました。

「http://localhost:8888/sql.php?db=go_auth&table=users&pos=0」にアクセスしてデータを確認したところ、問題なく登録されていました。

OKですね。長くなったきたので、ここまでにしましょう。
次回
次回も引き続き、Vue.jsを使ったフロントエンド開発を行います。
コメントを残す
コメントを投稿するにはログインしてください。