Boost Vue Form Accuracy with the v‑timely‑validate Directive
The article introduces the Vue v‑timely‑validate directive, explains how it shifts form validation from blur to change for faster error clearance, outlines form structure, validation principles, usage steps, and provides complete code examples for seamless integration into i‑form components.
v-timely-validate Directive
Vue directives act as a decorator pattern to simplify code logic. The v-timely-validate directive changes the validation trigger of form rules from blur to change , allowing errors to disappear promptly.
Directive Purpose
It modifies the validation timing so that error messages are cleared as soon as the user corrects the input.
Form Composition
A typical form consists of five parts: label, input (radio, checkbox, select, slider, etc.), placeholder, help‑tip, and error‑message. The error‑message serves as an enhanced help‑tip, providing more specific feedback based on rule priority.
Form Classification
Selection‑type forms should default to change as the validation trigger.
Input‑type forms initially validate on blur , then switch to change after the first validation.
Validation Principles
Avoid forcibly blocking user input; provide timely reminders instead.
Promptly notify users of errors.
Do not disturb normal input flow (e.g., use blur only for the first check).
Eliminate error messages as early as possible by switching to change .
Usage
Add v-timely-validate to an i-form component.
Set the name attribute on form elements that correspond to validation rules.
Configure rules to trigger on blur .
Include a help-tip element inside i-form-item and apply the tai-form-item-help-tip class.
Code Example
export default {
bind(el, binding, vnode) {
const { rules } = vnode.componentInstance;
if (!rules) { return; }
function blurToChange(name) {
const inputRules = rules[name];
if (!inputRules || !Array.isArray(inputRules) || inputRules.length === 0) { return; }
setTimeout(() => {
inputRules.forEach((item) => {
const clone = Object.assign({}, item, { trigger: 'change' });
const result = inputRules.find(j => _.isEqual(j, clone));
if (!result) { inputRules.push(clone); }
});
}, 500);
}
function handleSubmit() {
const keys = Object.keys(rules);
keys.forEach(blurToChange);
el.removeEventListener('submit', handleSubmit, true);
}
function handleBlur(event) {
const { name, tagName } = event.target;
if ((tagName !== 'INPUT' && tagName !== 'TEXTAREA') || !name) { return; }
blurToChange(name);
}
// Event listeners can use passive options for better performance
el.addEventListener('submit', handleSubmit, true);
el.addEventListener('blur', handleBlur, true);
},
}; <i-form v-timely-validate ref="iForm" :model="form" :rules="rules" @submit.native.prevent="handleSubmit">
<i-form-item label="用户账号" prop="account">
<i-input v-model="form.account" name="account" placeholder="请输入用户账号" />
<p class="form-tip-name form-tip">由小写字母,数字,下划线组成,字母开头,最长16个字符</p>
</i-form-item>
</i-form>TiPaiPai Technical Team
At TiPaiPai, we focus on building engineering teams and culture, cultivating technical insights and practice, and fostering sharing, growth, and connection.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
