iT邦幫忙

2024 iThome 鐵人賽

DAY 27
1
Modern Web

Vue 3 初學者:用實作帶你看過核心概念系列 第 27

Vue 3 用實作帶你看過核心概念 - Day 27:VeeValidate 表單驗證工具

  • 分享至 

  • xImage
  •  

文章背景圖

目錄

  • VeeValidate 基本使用 - 內建規則使用
  • VeeValidate 基本使用 - i18n 多國語系設定
  • VeeValidate 手動設置驗證及驗證訊息
  • 總結

在開發 Vue 應用程式時,表單驗證至關重要,它能確保使用者輸入的資料符合預期的格式和要求。今天來介紹一款專門用於 Vue 的表單驗證工具—VeeValidate v4。這個工具不僅能幫助開發者輕鬆實現表單驗證,還提供了靈活且可擴展的 API,讓開發者能根據不同的應用場景自訂驗證邏輯。

VeeValidate 基本使用 - 內建規則使用

VeeValidate 本身有訂定一系列常見的內建規則可以套用在表單欄位上驗證,例如:required(必填)、email(信箱驗證)、min(輸入長度最小限制)、max(輸入長度最大限制)等。

需要安裝@vee-validate/rules(定義 VeeValidate 內建規則)。

npm i @vee-validate/rules

VeeValidate 內建規則:

VeeValidate 內建規則

👉 官方網站 vee-validate 的內建規則說明

首先說明驗證規則觸發的時機點

  • 當欄位的值改變時(預設是監聽change事件,而不是input事件)
  • 當驗證規則改變時
  • 當欄位失去焦點(blur)時
  • 當表單被提交(submit)時,會觸發表單內所有欄位的驗證機制

以下是使用VeeValidate內建規則的表單驗證範例:

👉 表單 vee-validate rules 實作連結

流程說明

  1. 透過defineRule定義要使用到的規則名稱
  2. 欄位將rules prop 綁定定義的規則名稱

App.vue

<script>
import { Form, Field, ErrorMessage, defineRule } from 'vee-validate';
import { required, email, min } from '@vee-validate/rules';

// 定義使用到的規則
defineRule('required', required);
defineRule('email', email);
defineRule('min', min);

export default {
  components: {
    Form,
    Field,
    ErrorMessage,
  },
};
</script>

<template>
  <Form class="form" v-slot="{ errors }">
    查看錯誤訊息:{{ errors }}
    <label for="email">Email:</label>
    <Field
      name="email"
      id="email"
      placeholder="請輸入 Email"
      rules="required|email"
    />
    <ErrorMessage name="email" class="error-message" />
    <label for="password">Password:</label>
    <Field
      name="password"
      id="password"
      placeholder="請輸入 Password"
      rules="required"
    />
    <ErrorMessage name="password" class="error-message" />
    <button class="btn-submit" type="submit">送出!</button>
  </Form>
</template>

Field組件name屬性需要跟ErrorMessage組件name屬性對應在一起

我們可以藉由Day 22提到的slot 作用域插槽取得每個欄位的錯誤訊息,但目前僅能在不符合規則的情況下顯示{field} is not valid的預設訊息,接著我會一步一步帶大家修改這個訊息顯示的方式。

預設內建錯誤訊息(default)

VeeValidate 基本使用 - i18n 多國語系設定

在使用VeeValidate時,預設的錯誤訊息大多為英文。若想切換成中文或自訂錯誤訊息,可以透過 VeeValidatei18n套件來進行設定。你可以使用configure方法並搭配localize 函數,來將錯誤訊息切換為中文,或定義自訂的錯誤訊息。

需要安裝@vee-validate/i18n(定義 VeeValidate i18n 相關語系設定及方法)。

npm i @vee-validate/i18n

在預設情況下,VeeValidate官方已內建 56 個國家的語系字典,並與內建的驗證規則相結合,讓開發者能夠輕鬆進行語言切換與多語系支援。透過localize,我們可以動態設定應用程式中使用的語系,同時確保驗證訊息能隨語言轉換自動更新。

以官方提供的zh-TW.json字典檔為例,可以看到內建規則對應顯示的錯誤訊息:

👉 官方網站 vee-validate 語系檔位置

zh_TW 官方字典檔格式

接著我們將先前提供的案例加入多國語系的設定:

👉 表單 vee-validate rules(套用官方提供多國語系)實作連結

App.vue 匯入所需的多國語系字典檔並進行相應的設定:

import { Form, Field, ErrorMessage, defineRule, configure } from 'vee-validate';
import { required, email, min } from '@vee-validate/rules';
import { localize } from '@vee-validate/i18n';
import en from '@vee-validate/i18n/dist/locale/en.json';
import zh from '@vee-validate/i18n/dist/locale/zh_TW.json';

// 可以設定錯誤顯示的語系檔
configure({
  generateMessage: localize({
    en,
    zh,
  }),
});

// 預設啟動使用 zh 語系顯示錯誤訊息
localize('zh');

查看畫面可以發現當輸入格式不符合規則的時候,會根據定義的字典檔顯示錯誤訊息。

輸入不符合 email 及 min 自定規則 - zh 語系

接下來,我為按鈕設定了不同的語系切換功能,用戶可以透過點選按鈕切換介面語言。在完成語系切換後,用戶需要點擊「送出」按鈕,這將觸發表單的重新驗證,確保所有輸入符合新的語系設定的要求。

App.vue methods:

// 按鈕觸發方法,使用 localize 改變當前驗證使用語系
updateLanguage(languageVal) {
    localize(languageVal);
}

輸入不符合 email 及 min 自定規則 - en 語系

VeeValidate預設不會在每次input事件時觸發驗證,這是為了避免過於頻繁的檢查。若希望在輸入時進行即時驗證,可以使用validateOnInput選項來調整此行為。此設定既可以全局應用於所有表單,也可以在個別的<Field>組件中單獨配置。

App.vue 多國語系設定:

configure({
  generateMessage: localize({
    en,
    zh,
  }),
  // 加入後會啟動 input 事件偵測
  validateOnInput: true,
});

如果想要在更改語系的同時馬上顯示變更後語系的驗證結果,可以透過validate()的方法達成。

App.vue methods 修改後:

updateLanguage(languageVal) {
    //...略
    // 手動觸發組件內驗證方法
    this.$refs.form.validate();
}

App.Vue Template:

  <Form ref="form" class="form" @submit.prevent v-slot="{ errors }">
    <!-- ...略 -->
  </Form>

VeeValidate 手動設置驗證及驗證訊息

前面都是透過VeeValidate內建的規則及i18n錯誤訊息,但實際開發當中有更多是需要自定義較為複雜的驗證邏輯及顯示不同的狀態。

這邊我們首先來嘗試自定義錯誤訊息

👉 vee-validate 表單 i18n 多國語系(自定義訊息)實作連結

自定義錯誤訊息

App.vue 多國語系設定:

configure({
  generateMessage: localize({
    zh: {
      messages: {
        ...zh.messages,
        // 自定義 required 欄位錯誤訊息蓋過預設 i18n 字典檔內的設定
        required: '🐱 此欄位為必填',
      },
    },
    en: {
      messages: {
        ...en.messages,
        // 自定義 required 欄位錯誤訊息蓋過預設 i18n 字典檔內的設定
        required: '🐯 This field is required',
      },
    },
  }),
});
// 預設啟動使用 zh 語系顯示錯誤訊息
localize('zh');

接著我們換成設定一個自定義的規則phone驗證電話號碼是否為十碼

👉 vee-validate 表單 i18n 多國語系(自定義訊息)實作連結

phone 自定義驗證邏輯

App.vue 多國語系設定:

// 自定義驗證規則:phone(暫定電話號碼是十碼)
defineRule('phone', (value) => {
  const phoneRegex = /^\d{10}$/;
  return phoneRegex.test(value);
});

configure({
  generateMessage: localize({
    zh: {
      messages: {
        ...zh.messages,
        required: '🐱 此欄位為必填',
        phone: '🐱 手機格式必須是數字十碼',
      },
    },
    en: {
      messages: {
        ...en.messages,
        required: '🐯 This field is required',
        phone: '🐯 The mobile phone format must be 10 digits',
      },
    },
  }),
  // 加入後啟動全局 input 觸發偵測
  validateOnInput: true,
});

台灣的電話號碼是 10 碼,但是不同國家的電話號碼長度規則不同(EX:俄羅斯有 11 碼的電話號碼),我們試著將上面的自定義規則在擴展得更有彈性,能讀取動態的參數影響長度的規則。

👉 vee-validate 表單 i18n 多國語系(自定義驗證規則 + 使用動態參數)實作連結

動態參數傳入錯誤訊息

App.Vue 自定義規則:

// 取得動態傳入 country 欄位的值
defineRule('phone', (value, [country]) => {
  const phoneRegex = country === 'TW' ? /^\d{10}$/ : /^\d{11}$/;
  return phoneRegex.test(value);
});

App VeeValidate 全局設定:

configure({
  generateMessage: localize({
    zh: {
      messages: {
        ...zh.messages,
        required: '🐱 此欄位為必填',
        phone: (context) => {
          const selectContry = context.form.country || 'TW';
          return `🐱 ${selectContry} 地區,手機格式必須是${
            selectContry === 'TW' ? '10' : '11'
          }位數字`;
        },
      },
    },
    en: {
      messages: {
        ...en.messages,
        required: '🐯 This field is required' || 'TW',
        phone: (context) => {
          const selectContry = context.form.country;
          return `🐯 ${selectContry} region,The mobile phone format must be ${
            selectContry === 'TW' ? '10' : '11'
          } digits`;
        },
      },
    },
  }),
  // 加入後啟動全局 input 觸發偵測
  validateOnInput: true,
});

App.vue Vue Template(rules 的部分改成動態綁定):

<!-- 使用 vallues 讀取表單欄位值 -->
<Form
ref="form"
class="form"
@submit="onFormSubmit"
v-slot="{ values, errors }"
>
    <!-- 使用 :rules 綁定動態的 country 值 -->
    <label for="phone">Phone:</label>
    <Field
      name="phone"
      id="phone"
      placeholder="請輸入 Phone"
      :rules="{ required: true, phone: values.country }"
    />
    <ErrorMessage name="phone" class="error-message" />
</Form>

總結

VeeValidate是一個強大且靈活的 Vue 表單驗證工具,它不僅提供豐富的內建驗證規則,還支援多國語系設定和自訂驗證邏輯。透過簡單的配置,開發者可以輕鬆實現從基礎到複雜的表單驗證需求,同時能夠根據需要自訂錯誤訊息和驗證觸發時機,大大簡化了表單驗證的開發流程。


上一篇
Vue 3 用實作帶你看過核心概念 - Day 26:KeepAlive 與 Teleport 內置組件
下一篇
Vue 3 用實作帶你看過核心概念 - Day 28:官方 Vue Router 的應用與技巧
系列文
Vue 3 初學者:用實作帶你看過核心概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言