在網頁開發中,常見的功能包括登入、註冊與各式表單等等這些功能,
那前端有個很重要的職責就是提前做好格式驗證。
這麼做的原因主要有三點:
但不代表前端做了後端就不用做,反之亦然。
總之今天我們將會用 Vee-validate + Yup 來創建自定義的驗證元件。
在 vee-validate 裡面呢,提供了非常多驗證相關的 API,
讓你可以跟其他元件或是 Library 合併使用。
主要有兩種使用方式 :
Composition API :
使用彈性較大,但要花比較久的時間配置。
HOC ( High-order component ) :
Vee-validate 提供了一些簡易的元件,
讓你不用寫一大堆 JS,就能快速體驗功能,但只能在 <template>
內使用。
那為了後續我們使用能連貫,接下來會用 Composition API 來做示範。
這是一個協助我們建立 schema
的一個工具,
方便我們後續使用這個 schema
和 vee-validate
合作來達成驗證的這個功能
那當然還有其他很棒的工具,
例如 zod,加上 ts-rest 在建立型別安全上有很強的地位,
不過這就會讓此篇文章變得太發散,因此有興趣的可能再去查找資料看看。
註解
schema 是一種描述資料格式和數值的架構,類似規則的概念。
$ npm i vee-validate yup
首先呢,我們先來建立具有驗證功能的 Input,
那根據官網的文件我們可以使用 useField()
這個 API。
import { useField } from "vee-validate";
import * as yup from "yup";
const { value, errorMessage } = useField(
"email",
/*第一個參數,欄位名稱,用來綁定。*/
yup.string().email("請輸入有效的電子郵件地址").required("此項為必填")
/*第二個參數,驗證規則。*/
);
並從中解構出 value
和 errorMessage
兩個值。
<script setup>
import { useField } from "vee-validate";
import * as yup from "yup";
const { value, errorMessage } = useField(
"email",
yup.string().email().required()
);
</script>
<template>
<div>
<label for="email">Email</label>
<input id="email" v-model="value" />
<span>{{ errorMessage }}</span>
</div>
</template>
▲ 自定義驗證 Input 元件
那這邊注意一下,其實我們是不用使用 v-model
的,
因為第一個參數 name
可以讓我們拿來做綁定。
所以我們的程式碼可以變成這樣:
- <input id="email" v-model="value" />
+ <input id="email"/>
▲ 因為 useField
會綁 input 的 name
,所以不需要再定義 v-model
但目前我們是欄位名稱是寫死的,這樣並無法複用,
因此我們可以定義一個 name
prop。
<script setup>
import { useField } from "vee-validate";
import { computed } from "vue";
import * as yup from "yup";
+ const { name } = defineProps({ name: String });
- const { value, errorMessage } = useField("email",
- yup.string().email("請輸入有效的電子郵件地址").required("此項為必填")
- );
+ const { value, meta, errorMessage, handleChange, handleBlur } = useField(name);
// 不同操作的判斷機制,詳情可以查詢 DOM Events
const events = {
change: handleChange,
input: (e) => handleChange(e, false),
blur: (e) => handleBlur(e, true),
};
// 錯誤機制處理
const invalid = computed(() => meta?.touched && !meta?.valid);
</script>
<template>
<div>
<label :for="name">{{ name }}</label>
<input :id="name" :name="name" :value="value" v-on="events" />
<span v-if="invalid" style="color: red">{{ errorMessage }}</span>
</div>
</template>
▲ 自定義驗證 Input 元件
驗證規則我們這邊先給他拿掉,接下來我們會使用 useForm()
處理。
<!-- App.vue -->
<script setup>
import { useForm } from "vee-validate";
import ValidateInput from "./views/ValidateInput.vue";
import * as yup from "yup";
useForm({
validationSchema: yup.object({
email: yup
.string()
.email("請輸入有效的電子郵件地址")
.required("此項為必填"),
}),
});
</script>
<template>
<div>
<ValidateInput name="email" />
</div>
</template>
▲ 父元件
那基本上那這邊我們就完成了自定義 Input + useForm 驗證,
vee-validate 其實還提供了非常多 API,但由於篇幅有限,這邊不多做說明;
下一篇將會透過 Vue router + Pinia + Vee-validate + Yup 達成跨頁驗證功能;
如果喜歡今天的文章,對這個系列感興趣,記得按下讚並 訂閱
追蹤文章,
或是分享給你身邊有在使用 Vue 的朋友。
useField()
是用來做什麼的 ?useForm()
是用來做什麼的 ?schema
,跟 Yup 的關係是什麼?