VeeValidate & Yup in Vue3 多語系檢驗訊息

Vue 3 的表單欄位檢驗有 VeeValidation 或是 Vuelidate,若使用 primevue 元件,則建議可以使用 VeeValidation ,它有一些程式範例可以參考及線上執行範例,它還可以結合 yup through @vee-validate/yup package 使用。

要讓表單可以有多語系支援,作法如下:

Step01 : 安裝套件

首先,在 Vue3 的專案下確保已經安裝了必要的依賴套件:

npm install vue@next vee-validate vue-i18n @vee-validate/yup --save

Step02: 設置 i18n

接著,創建一個 Vue 3 項目並設置 i18n,在 src/plugins 目錄下創建一個 vue-i18n.js 文件

import { createI18n } from 'vue-i18n';

const messages = {
  en: {
    required: 'This field is required',
    email: 'This field must be a valid email',
  },
  zh: {
    required: '此字段為必填項',
    email: '此字段必須是有效的電子郵件',
  },
};

const i18n = createI18n({
    legacy: false, // 要把 legacy 設為 false,才可以使用 Composition API
    locale: 'zh-TW', // 默認語言
    fallbackLocale: 'en-US',
    globalInjection: true,
    messages,
})

export default i18n;

Step03: 設置 Yup

在 src/plugins 目錄下創建一個 validation.js 文件

import * as yup from 'yup';
import i18n from '@/plugins/vue-i18n'
const { t } = i18n.global;

yup.setLocale({
    mixed: {
        required: () => `${t('validate.required')}`,
      },
      string: {
        email: () => `${t('validate.email')}`,
        min: ({ min }) => `${t('validate.field_too_short', { value: min })}`,
        max: ({ max }) => `${t('validate.field_too_big', { value: max })}`,
      },

      // use functions to generate an error object that includes the value from the schema
      number: {
        min: ({ min }) => ({ key: 'validate.field_too_short', value: { min } }),
        max: ({ max }) => ({ key: 'validate.field_too_big', value: { max } }),
      },
      // 其他錯誤訊息設定...
  });

  export default yup

Step04: 主要 Vue 入口頁面 App.vue 作測試

<template>
  <div id="app">
    <form novalidate @submit="onSubmit">
      <div>
        <label for="email">Email:</label>
        <input v-model="email" required placeholder="E-mail" :class="{ 'p-invalid': errors.email }" type="text" id="email" />
        <span>{{ errors.email }}</span>
        
        <input type="password" v-model="password" required  placeholder="Password" :class="{ 'p-invalid': errors.password }" />
        <span>{{ errors.password }}</span>
      </div>
      <button type="submit">Submit</button>
    </form>
    <button @click="changeLanguage('en')">English</button>
    <button @click="changeLanguage('zh')">中文</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import AppConfig from '@/layout/AppConfig.vue'
import { useToast } from 'primevue/usetoast'
import { useRouter } from 'vue-router'
import { useForm } from 'vee-validate'
import * as yup from 'yup'
import i18n from '@/plugins/vue-i18n'

const { t } = i18n.global
const processing = ref(false)
const toast = useToast()
const router = useRouter()

const schema = yup.object({
    email: yup.string().required().email(),
    password: yup.string().required().min(6).max(10)
})
const {  defineField, handleSubmit, resetForm, errors, values } = useForm({
    validationSchema: schema
})
const [email] = defineField('email')
const [password] = defineField('password')

const changeLanguage = (locale) => {
  i18n.global.locale.value = locale;
  resetForm();
};
const onSubmit = handleSubmit( async (values) => {
    try {
        processing.value = true
        const response = await axios.post('/api/auth/login',{
            email: values.email,
            password: values.password
        })
        // 在這裡處理登入成功的邏輯
        router.push({name:'dashboard'})
        setTimeout(() => {
            toast.add({ severity: 'info', summary: t('toast.info'), detail: t('toast.login_success'), life: 3000 })
        }, 500);

    } catch (e) {
        toast.add({ severity: 'error', summary: t('toast.error'), detail: t('toast.login_failed'), life: 3000 })        
    } finally {
        processing.value = false
    }
})
</script>

Step05: 主要Vue入口js文件main.js

import { createApp } from 'vue';
import App from './App.vue';
import i18n from '@/plugins/vue-i18n';
import '@/plugins/yup'

const app = createApp(App);
app.use(i18n);
app.mount('#app');

這樣,就完成了一個簡單的 Vue 3 應用,使用 Yup 進行驗證並支持多語系。可以通過點擊按鈕切換語言,表單驗證消息也會隨之改變。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *