跳到主要內容
前端開發

vee-validate 表單驗證安裝紀錄(v3,Options API)

記錄在 Nuxt 2 安裝 vee-validate 3.x 的完整過程——全域註冊規則與中文語系、用 ValidationProvider 包裹單一欄位、用 ValidationObserver 統一驗證整份表單再送出,以及安裝規則檔時會撞到的 Unexpected token export 錯誤跟修法。vee-validate 4 已經全面改成 Composition API,整理在新的一篇。

W

調整表單驗證,用了 vee-validate 這套套件,踩了不少坑,整理一次完整流程。

安裝

npm install vee-validate --save

plugins/vee-validate.js

import Vue from 'vue';
import { ValidationObserver, ValidationProvider, extend, localize } from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';
import zhTW from 'vee-validate/dist/locale/zh_TW.json';
import { required, email } from 'vee-validate/dist/rules'; // 按照需求導入規則

Object.keys(rules).forEach((rule) => {
  extend(rule, rules[rule]);
});

extend('required', required);
extend('email', email);

localize('zh_TW', zhTW);

Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);

nuxt.config.js 註冊這支 plugin:

export default {
  plugins: [{ src: '~plugins/vee-validate', ssr: true }],
};

單一欄位驗證:ValidationProvider

<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate';

export default {
  components: { ValidationProvider, ValidationObserver },
};
</script>
<ValidationProvider rules="required|email" v-slot="{ errors }">
  <input type="email" v-model="form.user.email" placeholder="請輸入 Email">
  <span class="text-danger">{{ errors[0] }}</span>
</ValidationProvider>

rules="required|email" 用直式分隔多個規則,v-slot="{ errors }" 拿到這個欄位目前的錯誤訊息陣列,沒有錯誤時 errors 是空陣列。

整份表單驗證:ValidationObserver

<ValidationObserver tag="form" ref="observer" @submit.prevent="createOrder">
  <div class="form-group">...</div>
  <div class="form-group">...</div>
  <div class="text-right">
    <button type="submit">送出</button>
  </div>
</ValidationObserver>
methods: {
  createOrder() {
    this.$refs.observer.validate().then((result) => {
      if (result) {
        this.$axios.$post(url, { data: order }).then((res) => {
          if (res.success) {
            this.$router.push(`/customerCheckOut/${res.data.orderId}`);
          }
        });
      } else {
        console.log('訂單未完成');
      }
    });
  },
}

this.$refs.observer.validate() 會一次驗證這個 ValidationObserver 底下所有 ValidationProvider,回傳一個 Promise,結果是布林值——全部通過才是 true,任何一個欄位沒過就是 false,這時候各欄位自己的錯誤訊息也會自動顯示出來,不需要自己手動去組合錯誤清單。

踩到的坑:Unexpected token export

安裝規則檔時撞到:

Unexpected token export

原因是 vee-validate/dist/rules 這個檔案是用 ES Module 格式(export)寫的,而 Nuxt 預設不會轉譯 node_modules 底下的檔案(避免每個第三方套件都要重新編譯一次,拖慢建置速度),但這個規則檔沒有先被轉譯成瀏覽器看得懂的格式,就直接被拿去執行,才會噴出這個錯誤。

修法是在 nuxt.config.js 明確把這個路徑加進轉譯清單的例外:

export default {
  build: {
    transpile: ['vee-validate/dist/rules'],
  },
};

這是官方文件裡明確寫的解法——node_modules 底下的東西預設不轉譯,遇到少數幾個「明明是第三方套件但沒有先編譯好」的情況,就要手動加進 transpile 清單。

現在還適用嗎

ValidationObserverValidationProvider 這套元件式的寫法屬於 vee-validate 3.x(v2 的用法也類似),vee-validate 4 已經全面改成 Composition API 風格,useFielduseForm 取代了整組元件,整理在《vee-validate 4:改用 Composition API》。

參考資料

分享這篇