iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
Vue.js

在 Vue 過氣前要學的三十件事系列 第 25

在 Vue 過氣前要學的第二十五件事 - 我真的不是機器人 / 跨頁表單驗證 ( 中 ) / Vee-validate & Yup

  • 分享至 

  • xImage
  •  

前言

在網頁開發中,常見的功能包括登入、註冊與各式表單等等這些功能,
那前端有個很重要的職責就是提前做好格式驗證

這麼做的原因主要有三點:

  1. 減少不必要的 API 請求,避免後端被過多無效請求佔用資源。
  2. 確保送往後端的資料格式正確,降低後端驗證與錯誤處理的負擔。
  3. 提升使用者體驗,能即時提示錯誤並引導使用者快速修正。

但不代表前端做了後端就不用做,反之亦然。

總之今天我們將會用 Vee-validate + Yup 來創建自定義的驗證元件。

基礎概念

vee-validate

在 vee-validate 裡面呢,提供了非常多驗證相關的 API,
讓你可以跟其他元件或是 Library 合併使用。

主要有兩種使用方式 :

  1. Composition API :
    使用彈性較大,但要花比較久的時間配置。

  2. HOC ( High-order component ) :
    Vee-validate 提供了一些簡易的元件,
    讓你不用寫一大堆 JS,就能快速體驗功能,但只能在 <template> 內使用。

那為了後續我們使用能連貫,接下來會用 Composition API 來做示範。

yup

這是一個協助我們建立 schema 的一個工具,

方便我們後續使用這個 schemavee-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("此項為必填")
  /*第二個參數,驗證規則。*/
);

並從中解構出 valueerrorMessage 兩個值。

<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 達成跨頁驗證功能;
https://ithelp.ithome.com.tw/upload/images/20250924/20172784ZMaO2Ielj2.png

如果喜歡今天的文章,對這個系列感興趣,記得按下讚並 訂閱 追蹤文章,
或是分享給你身邊有在使用 Vue 的朋友。

一些小練習

  1. useField() 是用來做什麼的 ?
  2. useForm() 是用來做什麼的 ?
  3. 簡單解釋 schema,跟 Yup 的關係是什麼?

上一篇
在 Vue 過氣前要學的第二十四件事 - 蟹老闆你有感覺了嗎 / 跨頁表單驗證 ( 上 ) / Pinia
下一篇
在 Vue 過氣前要學的第二十六件事 - Avengers Assemble!
系列文
在 Vue 過氣前要學的三十件事26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言