完成サンプル
たとえば、未入力のままREGISTER(登録)
ボタンをクリックすると...
ページ上部にAlertメッセージの表示とバリデートチェックで引っかかった項目を赤字で表示するようにしてみます。
Vuetify3とは?
Vuetify3
は、Vue3向けのUIフレームワークです。これらのUIフレームワークを使用することで統一感のあるデザインと開発工数を効率化を図ることができます。
今回は、Alert Component
を使って実装しています。
完成コード
まず菅聖子度をお見せします。
<script setup lang="ts">
import { ref } from 'vue';
import { useField, useForm } from 'vee-validate';
import * as yup from 'yup';
import axios from 'axios';
import { useRouter } from 'vue-router';
const formRef = ref(null);
const { handleSubmit } = useForm();
const router = useRouter();
/*---Name validation---*/
const nameField = useField(
'name',
yup.string().required('Name must be required.').min(2, 'Please input over 1 character.')
);
const { value: name, errorMessage: nameerror } = nameField;
/*---Email validation---*/
const emailField = useField(
'email',
yup.string().required('Email must be required.').matches(/^[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)*@([a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]\.)+[a-zA-Z]{2,}$/, { message: 'Mail address is invalid' })
);
const { value: email, errorMessage: emailerror } = emailField;
/*---Password validation---*/
const passwordField = useField(
'password',
yup.string().required('Password must be required.').min(2, 'Please input over 1 character.').max(11, 'The password is too long. Please input until 10 characters.')
);
const { value: password, errorMessage: passworderror } = passwordField;
/*---Gender validation---*/
const genderField = useField(
'gender',
yup.string().required('Gender must be required.')
);
const { value: gender, errorMessage: gendererror } = genderField;
/*---Survey validation---*/
const surveyField = useField<string[]>(
'survey',
yup.array().of(yup.string()).min(1, 'Please choose at least one.'),
{initialValue:[]} // 配列の長さが1以上であることを確認
);
const { value: survey } = surveyField;
const nameErrorMessage = ref('');
const emailErrorMessage = ref('');
const passwordErrorMessage = ref('');
const genderErrorMessage = ref('');
const surveyErrorMessage = ref('');
/** Set alert bar on header */
const globalError = ref('');
const showAlert = ref(false);
/** Define formData validate flag */
const flagForValidate = ref(true);
const surveyOptions = [
'I want to know from News letters',
'I want to know from Campaign',
'I want to know from Events'
];
const onSubmit = async()=>{
try{
/** Initialize validate flag. */
flagForValidate.value = true;
/** Hidden alert display */
showAlert.value = false;
/** Initialize error message */
nameErrorMessage.value = '';
emailErrorMessage.value = '';
passwordErrorMessage.value = '';
genderErrorMessage.value = '';
surveyErrorMessage.value = '';
/** Define FormData object */
const formData = new FormData();
/** Validate value of name if name is empty or not. */
if(name.value === '' || name.value === undefined){
nameErrorMessage.value = 'Please input your name.';
/** Update value of flag */
flagForValidate.value = false;
}
formData.append('name',name.value);
/** Validate value of email if email is empty or not. */
if(email.value === '' || email.value === undefined){
emailErrorMessage.value = 'Please input your email.';
/** Update value of flag */
flagForValidate.value = false;
}
formData.append('email',email.value);
/** Validate value of password if password is empty or not. */
if(password.value === '' || password.value === undefined){
passwordErrorMessage.value = 'Please input your password.';
/** Update value of flag */
flagForValidate.value = false;
}
formData.append('password',password.value);
/** Validate value of gender if gender is empty or not. */
if(gender.value === '' || gender.value === undefined){
genderErrorMessage.value = 'Please input your gender.';
/** Update value of flag */
flagForValidate.value = false;
}
formData.append('gender',gender.value);
/** Validate value of gender if gender is empty or not. */
if(survey.value.length === 0 || survey.value === undefined){
surveyErrorMessage.value = 'Please input your survey.';
/** Update value of flag */
flagForValidate.value = false;
}
/** Evaluate value of flag:if this is false,show alert message on header.*/
if(!flagForValidate.value){
showAlert.value = true;
globalError.value = 'Invalide some values on the form.Please confirm and input data.';
return;
}
formData.append('survey',JSON.stringify(survey.value));
console.log('survey.value:', survey.value);
console.log(...formData.entries());
const response = await axios.post('http://localhost:8000/api/creategeneraluser/',formData);
if(response.status === 201){
alert('Sucess');
console.log(response);
router.push('/dashboard/dashboard');
}else{
alert('>>');
}
}catch(error){
alert('error');
console.log(error);
}
}
//const router = useRouter();
const clickBackToTopPage = () => {
router.push('/');
};
</script>
<template>
<v-app>
<v-alert
v-if="showAlert"
:text="globalError"
type="error"
title="Invalide Error"
class="mt-2 mb-4"
border="start"
variant="tonal"
color="error"
icon="$error"
prominent
></v-alert>
<v-main>
<v-container class="mt-5">
<v-form @submit.prevent="onSubmit" ref="formRef">
<!-- Name -->
<v-text-field
v-model="name"
label="Name"
required
></v-text-field>
<span>{{ nameerror }}</span>
<span style="color:red;">{{ nameErrorMessage }}</span>
<!-- Mail Address -->
<v-text-field
v-model="email"
label="Email"
type="email"
required
></v-text-field>
<p>{{ emailerror }}</p>
<span style="color:red;">{{ emailErrorMessage }}</span>
<!-- Password -->
<v-text-field
v-model="password"
label="Password"
type="password"
required
></v-text-field>
<p>{{ passworderror }}</p>
<span style="color:red;">{{ passwordErrorMessage }}</span>
<!-- Gender (radio button) -->
<v-radio-group
v-model="gender"
label="Sex"
row
>
<v-radio label="man" value="man"></v-radio>
<v-radio label="woman" value="woman"></v-radio>
<v-radio label="other" value="other"></v-radio>
</v-radio-group>
<p>{{ gendererror }}</p>
<span style="color:red;">{{ genderErrorMessage }}</span>
<br/>
<!-- Survey (checkboxes) -->
<v-label>Survey</v-label>
<v-row>
<v-col cols="12" v-for="option in surveyOptions" :key="option">
<v-checkbox
:label="option"
:value="option"
v-model="survey"
hide-details
/>
</v-col>
</v-row>
<span style="color:red;">{{ surveyErrorMessage }}</span>
<br/>
<!--
<v-selection-group v-model="survey" multiple>
<v-checkbox
v-for="option in surveyOptions"
:key="option"
:label="option"
:value="option">
</v-checkbox >
</v-selection-group>
<p>{{ surveyerror }}</p>
-->
<!-- Submit button -->
<v-btn type="submit" color="primary" class="mr-4">Register</v-btn>
<v-btn type="button" color="success" @click="clickBackToTopPage">BackToTopPage</v-btn>
</v-form>
</v-container>
</v-main>
</v-app>
</template>
コードの説明
Yup
の導入
Yup
は、バリデーションチェックを行うためのライブラリです。
Yup
を使えば、バリデーションのカスタマイズを柔軟に行うことができます。
import * as yup from 'yup';
/*---Name validation---*/
const nameField = useField(
'name',
yup.string().required('Name must be required.').min(2, 'Please input over 1 character.')
);
const { value: name, errorMessage: nameerror } = nameField;
Vuetify3-Alert Components
の導入
今回は、Register
ボタンを押下してエラーを検知した時にページ上部にAlertメッセージを表示させます。
そのため、v-alert
コンポーネントを使ってオブジェクトを作成しましょう。
//Set alert bar on header
const globalError = ref('');
const showAlert = ref(false);
<v-alert
v-if="showAlert"
:text="globalError"
type="error"
title="Invalide Error"
class="mt-2 mb-4"
border="start"
variant="tonal"
color="error"
icon="$error"
prominent
></v-alert>
const globalError = ref('');
は、Alertメッセージの内容を埋め込むためのオブジェクトです。
const showAlert = ref(false);
は、v-alert
をBoolean値に応じて動的に制御するオブジェクトです。
各項目が空の場合のエラー表示
たとえば、v-model
の摂る双方向ばいディング値がname
の値が空の場合に<span />
タグにエラーメッセージを表示する方法です。
const nameErrorMessage = ref('');
/** Validate value of name if name is empty or not. */
if(name.value === '' || name.value === undefined){
nameErrorMessage.value = 'Please input your name.';
/** Update value of flag */
flagForValidate.value = false;
}
formData.append('name',name.value);
ref
使って初期化('')します。
バリデーションエラーがった場合は、メッセージをnameErrorMessage
に入れるのですが上記のように入れます。
nameErrorMessage.value = 'Please input your name.';
誤ってnameErrorMessage = 'Please input your name.';
としてしまうと直接文字列を代入 すると、Vue のリアクティビティが壊れます。これは ref オブジェクト自体を上書きしているためです。
以上です。