Vuelidate Vue3表單驗證套件|自訂驗證規則 錯誤訊息

Wendy Chang
Wendy Loops
Published in
12 min readDec 7, 2023

是時候來驗證表單了!這次使用的是Vuelidate這個套件!

會選用Vuelidate的原因是,我使用的是Vuetify這個UI framework,而Vuetify form中有VuelidateVee-validate的範例程式碼,於是我就選了Vuelidate(想說官方都推薦就隨便選一個來用用看)。

Vuelidate文件

安裝

npm install @vuelidate/core @vuelidate/validators

引入useVuelidate

// Vue3 setup hook
// vuelidate核心
import { useVuelidate } from '@vuelidate/core'
// 等等會用到的驗證工具
import { email, required } from '@vuelidate/validators'

先來設計一個註冊表單!

  <form>
<v-text-field
label="E-mail"
required
></v-text-field>

<v-text-field
label="Password"
required
type="password"
></v-text-field>

<v-text-field
label="Password confirm"
required
type="password"
></v-text-field>
<v-btn class="me-4"> submit </v-btn>
</form>

塞v-model進去

import { reactive } from "vue";

const state = reactive({
email: "",
password: {
password: "",
confirm: "",
},
});
  <form>
<v-text-field
v-model="state.email"
label="E-mail"
required
></v-text-field>

<v-text-field
v-model="state.password.password"
label="Password"
required
type="password"
></v-text-field>

<v-text-field
v-model="state.password.confirm"
label="Password confirm"
required
type="password"
></v-text-field>

<v-btn class="me-4"> submit </v-btn>
</form>

submit按鈕掛一個click事件

<v-btn class="me-4" @click="submitForm"> submit </v-btn>

const submitForm = () =>{
// TODO: 驗證
}

呼叫submitForm()同時要讓他能驗證,所以要來寫一下驗證規則:

required: 必填欄位
minLength: 最短字元需多長
email: 電子信箱格式驗證
sameAs: 跟...長一樣

這些Vuelidate內建的驗證都可以在文件中找到。

import { email, required, minLength } from '@vuelidate/validators'
import { reactive, computed } from "vue";

const rules = computed(() => {
return {
email: {
required,
email
},
password: {
password: {
required,
minLength(10),
},
confirm: {
required,
sameAs(state.password.password)
},
},
};
});

const v$ = useVuelidate(rules, state); // 使用Vuelidate函式,傳入規則以及響應式資料
  • 註:若使用ref綁定則須注意:
<v-text-field
v-model="name"
label="name"
required
></v-text-field>

const name = ref(null)

const rules = computed(() => {
return {
name: { required: helpers.withMessage("此為必填項", required) },
};
});

// name需放入物件中!!!
const v$ = useVuelidate(rules, {name});

submit按鈕進行驗證

const submitForm = () =>{
v$.value.$validate();
console.log(v$.value); // 可以看一下驗證後的v$長怎樣
}

$error會回傳此驗證有沒有通過,可以依此來做alert

const submitForm = () => {
v$.value.$validate();

console.log(v$.value);
if (!v$.value.$error) {
alert("送出成功");
} else {
alert("失敗");
}
};

自定義驗證規則

有時候會有客製需求,這時候只需要引入helpers,並在後方加入正規表達式:

import { email, required, minLength, helpers } from '@vuelidate/validators'

// 1. 密碼不可與帳號相同
// 2. 密碼長度至少10碼。
// 3. 密碼應包含下列四種字元的三種:大寫英文(A到Z)、小英文(a到z)、數字(到9)、特殊符號(如:!、@、#、、%)。
const passwordRules = helpers.regex(
/^(?=(?:.*[A-Z]){1,})(?=(?:.*[a-z]){1,})(?=(?:.*[0-9]){1,})(?=(?:.*[!@#%]){1,}).{10,}$/
);

const rules = computed(() => {
return {
email: {
required,
email
},
password: {
password: {
required,
minLength(10),
passwordRules //寫在這裡
},
confirm: {
required,
sameAs(state.password.password)
},
},
};
});

這樣就可以用自定義的規則來驗證。

輸入時觸發驗證

但把驗證函式寫在最後的提交按鈕,只有在按下去之後才告訴你驗證有無成功,無法在輸入時就告訴你錯誤訊息,所以我們在input框也進行驗證,並且使用$touch函式。
$touch可以用來更新$dirty$dirty:有無觸發表單)。

  <form>
<v-text-field
v-model="state.email"
label="E-mail"
required
@input="v$.email.$touch" // 依據v-model格式
@blur="v$.email.$touch" // blur的時候觸發
></v-text-field>

<v-text-field
v-model="state.password.password"
label="Password"
required
type="password"
@input="v$.password.password.$touch"
@blur="v$.password.password.$touch"
></v-text-field>

<v-text-field
v-model="state.password.confirm"
label="Password confirm"
required
type="password"
@input="v$.password.confirm.$touch"
@blur="v$.password.confirm.$touch"
></v-text-field>
<v-btn class="me-4" @click="submitForm"> submit </v-btn>
</form>

接著增加error-messages屬性,可以即時告知使用者哪裡有錯;$errors是一個陣列,會顯示錯誤資訊,將$messgage提取出來顯示至畫面上。

  <form>
<v-text-field
v-model="state.email"
label="E-mail"
required
@input="v$.email.$touch"
@blur="v$.email.$touch"
:error-messages="emailErrorMsg"
></v-text-field>

<v-text-field
v-model="state.password.password"
label="Password"
required
type="password"
@input="v$.password.password.$touch"
@blur="v$.password.password.$touch"
:error-messages="passwordErrorMsg"
></v-text-field>
<v-text-field
v-model="state.password.confirm"
label="Password confirm"
required
type="password"
@input="v$.password.confirm.$touch"
@blur="v$.password.confirm.$touch"
:error-messages="confirmErrorMsg"
></v-text-field>
<v-btn class="me-4" @click="submitForm"> submit </v-btn>
</form>


// script setup
const emailErrorMsg = computed(() => {
let errors = [];
v$.value.email.$errors.forEach((error) => {
errors.push(error.$message);
});

return errors;
});

const passwordErrorMsg = computed(() => {
let errors = [];
console.log(v$.value)
v$.value.password.password.$errors.forEach((error) => {
errors.push(error.$message);
});

return errors;
});

const confirmErrorMsg = computed(() => {
let errors = [];
v$.value.password.confirm.$errors.forEach((error) => {
errors.push(error.$message);
});

return errors;
});

自定義錯誤資訊

全英文你的業主要看不懂了,所以在rules這邊進行修改:
引入helpers並呼叫withMessage,第一個參數傳入自定義文字,第二個參數傳入規則名稱。

const rules = computed(() => {
return {
email: {
required: helpers.withMessage("此為必填項", required),
email: helpers.withMessage("Email格式不合法", email),
},
password: {
password: {
required: helpers.withMessage("此為必填項", required),
minLength: helpers.withMessage("長度須超過10個字元", minLength(10)),
passwordRules: helpers.withMessage("大寫英文(A到Z)、小英文(a到z)、數字(0到9)、特殊符號(如:!、@、#、%)", passwordRules),
},
confirm: {
required,
sameAs: helpers.withMessage('需與密碼相同',sameAs(state.password.password)),
},
},
};
});

這樣就成功嚕。

其實Vuelidate算蠻簡單的,只要看懂console出來的v$,就可以依此去做校驗,很多參數屬性就查一下文件,也不會很難~

--

--

Wendy Chang
Wendy Loops

什麼都寫ㄉ前端工程師 / 影片剪輯師 / 自媒體經營者