Vuelidate Vue3表單驗證套件|自訂驗證規則 錯誤訊息
是時候來驗證表單了!這次使用的是Vuelidate這個套件!
會選用Vuelidate的原因是,我使用的是Vuetify這個UI framework,而Vuetify form中有Vuelidate跟Vee-validate的範例程式碼,於是我就選了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$,就可以依此去做校驗,很多參數屬性就查一下文件,也不會很難~