Nuxt3を利用した問い合わせフォームに確認画面を追加する
Table of contents
このチュートリアルでは、Newtの Form App と Nuxt3 を利用して作成された問い合わせフォームに、確認画面を追加する手順を紹介します。
VeeValidate を利用して、実装します。
記事内で使用している主なソフトウェアのバージョン
- Nuxt(
nuxt
): 3.10.3 - VeeValidate(
vee-validate
): 4.12.6
前提条件
- Nuxt3を利用した問い合わせフォームを作成済みであること
Nuxt3を利用した問い合わせフォームの作成方法について知りたい場合は、以下のドキュメントをご確認ください。
概要
Nuxt3で作成した問い合わせフォームに、入力内容の確認画面を追加します。
※ ここではスタイルについては扱いません。
実装としては、ページ内で状態を管理し、入力用の画面と確認用の画面を出し分けます。
作成される問い合わせフォームは以下のようになります。
1. 基本のフォーム
もともと、以下のような問い合わせフォームがあるとします。
基本的な問い合わせフォームの作成方法について知りたい場合は、NewtとNuxt3を利用して、問い合わせフォームを作成する のドキュメントをご確認ください。
1<script lang="ts" setup>
2import { useForm } from 'vee-validate'
3
4const config = useRuntimeConfig()
5
6const { defineField, handleSubmit } = useForm()
7const [name, nameProps] = defineField('name')
8const [email, emailProps] = defineField('email')
9const [message, messageProps] = defineField('message')
10
11const onSubmit = handleSubmit(async (values) => {
12 const formData = new FormData()
13 Object.entries(values).forEach(([key, value]) => {
14 formData.append(key, value)
15 })
16
17 try {
18 const response = await fetch(config.public.newt.formEndpoint, {
19 method: 'POST',
20 body: formData,
21 headers: {
22 Accept: 'application/json'
23 }
24 })
25
26 if (response.ok) {
27 await navigateTo('/thanks')
28 } else {
29 await navigateTo('/error')
30 }
31 } catch (err) {
32 await navigateTo('/error')
33 }
34})
35
36useHead({
37 title: 'Newt・Nuxtフォーム',
38 meta: [
39 { name: 'description', content: 'NewtとNuxtを利用した問い合わせフォームです' }
40 ]
41})
42</script>
43
44<template>
45 <div>
46 <h1>Contact us</h1>
47 <form @submit="onSubmit">
48 <label for="name">Name</label>
49 <input id="name" v-model="name" v-bind="nameProps" name="name">
50 <label for="email">Email</label>
51 <input id="email" v-model="email" v-bind="emailProps" name="email" type="email">
52 <label for="message">Message</label>
53 <textarea id="message" v-model="message" v-bind="messageProps" name="message" />
54 <button type="submit">
55 Submit
56 </button>
57 </form>
58 </div>
59</template>
2. 確認画面の追加
2-1. 状態の定義
入力用の画面と確認用の画面を出し分けるために isInput
という変数を定義します。
この isInput
が true
の場合は入力用の画面を表示し、false
の場合は確認用の画面を表示します。
<script lang="ts" setup>
import { useForm } from 'vee-validate'
const config = useRuntimeConfig()
const isInput = useState(() => true)
(省略)
2-2. 確認画面の追加
pages/contact.vue
を以下のように修正します。
ポイントは以下の通りです。
- 「Confirm」ボタンの押下時に、
isInput
をfalse
にする - 「Back」ボタンの押下時に、
isInput
をtrue
にする isInput
の値で入力画面と確認画面を出し分ける
※ 下記ではフォームの送信結果に応じて、/thanks
または /error
にリダイレクトしていますが、ここでは詳細は扱いません。興味のある方は、NewtとNuxt3を利用して、問い合わせフォームを作成する のチュートリアルをご確認ください。
1<script lang="ts" setup>
2import { useForm } from 'vee-validate'
3
4const config = useRuntimeConfig()
5const isInput = useState(() => true)
6
7const { defineField, handleSubmit } = useForm()
8const [name, nameProps] = defineField('name')
9const [email, emailProps] = defineField('email')
10const [message, messageProps] = defineField('message')
11
12const onConfirm = () => {
13 isInput.value = false
14}
15
16const goBack = () => {
17 isInput.value = true
18}
19
20const onSubmit = handleSubmit(async (values) => {
21 const formData = new FormData()
22 Object.entries(values).forEach(([key, value]) => {
23 formData.append(key, value)
24 })
25
26 try {
27 const response = await fetch(config.public.newt.formEndpoint, {
28 method: 'POST',
29 body: formData,
30 headers: {
31 Accept: 'application/json'
32 }
33 })
34
35 if (response.ok) {
36 await navigateTo('/thanks')
37 } else {
38 await navigateTo('/error')
39 }
40 } catch (err) {
41 await navigateTo('/error')
42 }
43})
44
45useHead({
46 title: 'Newt・Nuxtフォーム',
47 meta: [
48 { name: 'description', content: 'NewtとNuxtを利用した問い合わせフォームです' }
49 ]
50})
51</script>
52
53<template>
54 <div v-if="isInput">
55 <h1>Contact us</h1>
56 <label for="name">Name</label>
57 <input id="name" v-model="name" v-bind="nameProps" name="name">
58 <label for="email">Email</label>
59 <input id="email" v-model="email" v-bind="emailProps" name="email" type="email">
60 <label for="message">Message</label>
61 <textarea id="message" v-model="message" v-bind="messageProps" name="message" />
62 <button type="button" @click="onConfirm">
63 Confirm
64 </button>
65 </div>
66 <div v-else>
67 <h1>Please confirm your submission</h1>
68 <form @submit="onSubmit">
69 <table>
70 <tbody>
71 <tr>
72 <th>Name</th>
73 <td>{{ name }}</td>
74 </tr>
75 <tr>
76 <th>Email</th>
77 <td>{{ email }}</td>
78 </tr>
79 <tr>
80 <th>Message</th>
81 <td>{{ message }}</td>
82 </tr>
83 </tbody>
84 </table>
85 <div>
86 <button type="button" @click="goBack">
87 Back
88 </button>
89 <button type="submit">
90 Submit
91 </button>
92 </div>
93 </form>
94 </div>
95</template>
これで http://localhost:3000/contact
にアクセスすると、まず以下のようなフォームが表示されます。
フォームに内容を入力し、「Confirm」ボタンを押すと、以下のように表示されます。
「Back」を押すと入力画面に戻り、「Submit」を押すとフォームが送信されることが確認できます。