Vue Element Admin Validation.js Utility Pattern: A Complete Guide to Custom Validators
The validation.js utility in vue-element-admin provides pure, stateless functions that return booleans, which you wrap into Element UI form rules using callback-based validators to trigger error messages automatically.
The src/utils/validate.js module in PanJiaChen/vue-element-admin centralizes form validation logic through a collection of reusable utility functions. This validation.js utility pattern ensures consistent input checking across the application while maintaining testability and clean separation of concerns from UI components.
Core Architecture of the Validation.js Pattern
Stateless Boolean Validators
Each validator in src/utils/validate.js follows a strict functional contract: accept an input value and return a boolean indicating validity. According to the vue-element-admin source code, these utilities contain no side effects and rely on regular expressions or simple conditional checks.
The module exports individual functions that can be imported anywhere:
// src/utils/validate.js
export function validUsername(str) {
const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0
}
Element UI Integration
Element UI's form validation system expects rules to use a validator callback pattern. The validation.js utilities bridge to this API by wrapping boolean results in (rule, value, callback) => {} functions, calling callback() on success or callback(new Error('message')) on failure.
Implementing Form Validation in Components
Typical usage follows the pattern found in src/views/login/index.vue, where validators import from the utility module and integrate into the rules object:
// src/views/login/index.vue
import { validUsername } from '@/utils/validate'
export default {
data() {
return {
rules: {
username: [
{ required: true, message: 'Please input username', trigger: 'blur' },
{
validator: (rule, value, callback) => {
validUsername(value) ? callback() : callback(new Error('Invalid username'))
},
trigger: 'blur'
}
]
}
}
}
}
How to Add Custom Validators
Adding a custom validator requires three steps: extending the utility file, writing unit tests, and implementing the rule in your component.
Step 1: Extend validate.js
Create a new exported function in src/utils/validate.js that returns a boolean based on your validation logic:
// src/utils/validate.js
/**
* @param {string} password
* @returns {Boolean}
* Validates strong passwords: 8+ chars, uppercase, number, special character
*/
export function strongPassword(password) {
const reg = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[\S]{8,}$/
return reg.test(password)
}
Step 2: Write Unit Tests
Maintain reliability by adding test cases to tests/unit/utils/validate.spec.js:
// tests/unit/utils/validate.spec.js
import { strongPassword } from '@/utils/validate.js'
describe('Validation Utils', () => {
it('strongPassword', () => {
expect(strongPassword('Abcdef1!')).toBe(true)
expect(strongPassword('weakpass')).toBe(false)
expect(strongPassword('Short1!')).toBe(false)
})
})
Step 3: Use in Form Rules
Import the validator into your component and wrap it in the Element UI callback pattern:
import { strongPassword } from '@/utils/validate'
rules: {
password: [
{ required: true, message: 'Password required', trigger: 'blur' },
{
validator: (rule, value, callback) => {
strongPassword(value)
? callback()
: callback(new Error('Password must be 8+ chars with uppercase, number, special char'))
},
trigger: 'blur'
}
]
}
Additional Example: Phone Number Validation
Here is another custom validator pattern for phone number formatting:
// src/utils/validate.js
export function validPhoneNumber(num) {
const reg = /^(\+?\d{1,3}[- ]?)?\d{10}$/
return reg.test(num)
}
// Component implementation
import { validPhoneNumber } from '@/utils/validate'
rules: {
phone: [
{ required: true, message: 'Phone required', trigger: 'blur' },
{
validator: (rule, value, callback) => {
validPhoneNumber(value) ? callback() : callback(new Error('Invalid phone number format'))
},
trigger: 'blur'
}
]
}
Testing Your Validation Logic
The validation.js utility pattern emphasizes testability through pure functions. The existing test suite in tests/unit/utils/validate.spec.js validates each utility with Jest assertions, ensuring that changes to validation rules do not break existing functionality. Always add corresponding test cases when creating new validators to maintain code coverage and prevent regressions.
Summary
- Pure Functions: Validators in
src/utils/validate.jsare stateless, synchronous functions returning booleans. - Boolean Return: The pattern relies on
true/falsereturns that integrate with Element UI's callback-based validation API. - Reusable Architecture: Centralized utilities prevent duplication and ensure consistent validation rules across the application.
- Test Coverage: Unit tests in
tests/unit/utils/validate.spec.jsverify validator logic using Jest. - Integration Pattern: Wrap boolean validators in
(rule, value, callback) => {}functions to connect with Element UI form rules.
Frequently Asked Questions
Where are the validation utilities located in vue-element-admin?
The core validation utilities are located in src/utils/validate.js, with corresponding unit tests in tests/unit/utils/validate.spec.js. The login page at src/views/login/index.vue demonstrates practical implementation.
Why do validation.js functions return booleans instead of throwing errors?
The boolean return pattern keeps the utility functions pure and framework-agnostic. Element UI expects the validator callback to handle error reporting via callback(new Error()), so separating the boolean logic from the UI callback allows reuse across different contexts or UI libraries.
How do I test custom validators in vue-element-admin?
Add test cases to tests/unit/utils/validate.spec.js importing your new validator from @/utils/validate.js. Use Jest assertions like expect(yourValidator(value)).toBe(true) to verify both valid and invalid input cases.
Can I use async validators with this pattern?
Yes, while the validation.js utilities are synchronous, Element UI supports async validators. You can wrap the boolean check in a Promise or use async/await within the validator callback function before calling callback() or callback(new Error()).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →