963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
4.6 KiB
4.6 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| Use Event Validation for Complex Payloads | LOW | Event validation catches payload errors early with console warnings during development | best-practice |
|
Use Event Validation for Complex Payloads
Impact: LOW - Vue allows you to validate event payloads using object syntax for defineEmits. When a validation function returns false, Vue logs a console warning. This helps catch bugs early during development, especially for events with complex payload requirements.
Task Checklist
- Use object syntax for
defineEmitswhen validation is needed - Return
truefor valid payloads,falsefor invalid - Add meaningful console warnings in validators
- Consider TypeScript for compile-time validation instead
Basic Validation
Using object syntax with validators:
<script setup>
const emit = defineEmits({
// No validation - just declaration
cancel: null,
// Validate that email is present
submit: (payload) => {
if (!payload || !payload.email) {
console.warn('Submit event requires an email field');
return false;
}
if (!payload.email.includes('@')) {
console.warn('Submit event requires a valid email');
return false;
}
return true;
},
// Validate ID is a number
select: (id) => {
if (typeof id !== 'number') {
console.warn('Select event requires a numeric ID');
return false;
}
return true;
},
});
function handleSubmit(formData) {
// If validation fails, Vue logs warning but event still emits
emit('submit', formData);
}
</script>
What Happens on Validation Failure
<script setup>
const emit = defineEmits({
submit: (data) => {
if (!data?.email) {
return false; // Validation fails
}
return true;
},
});
function badSubmit() {
emit('submit', {}); // Missing email
// Console: [Vue warn]: Invalid event arguments: event validation failed for event "submit"
// Event STILL fires - validation is advisory only
}
</script>
Important: Validation failure only logs a warning. The event still emits. This is intentional for development debugging, not runtime enforcement.
Common Validation Patterns
Required Fields
const emit = defineEmits({ 'user-created': (user) => { const required = ['id', 'name', 'email']
const missing = required.filter(field => !user?.[field]) if (missing.length) {
console.warn(`user-created missing fields: ${missing.join(', ')}`) return false } return true } })
Type Checking
const emit = defineEmits({ 'page-change': (page) => typeof page === 'number' && page > 0,
'items-selected': (items) => Array.isArray(items), 'filter-applied': (filter) => { return filter &&
typeof filter.field === 'string' && filter.value !== undefined } })
Range Validation
const emit = defineEmits({ 'rating-change': (rating) => { if (typeof rating !== 'number' || rating <
1 || rating > 5) { console.warn('Rating must be a number between 1 and 5') return false } return
true } })
TypeScript Alternative
For compile-time validation, prefer TypeScript types over runtime validators:
<script setup lang="ts">
interface SubmitPayload {
email: string;
password: string;
rememberMe?: boolean;
}
const emit = defineEmits<{
submit: [payload: SubmitPayload];
cancel: [];
'page-change': [page: number];
}>();
// TypeScript catches errors at compile time
emit('submit', { email: '[email protected]' });
// Error: Property 'password' is missing
</script>
TypeScript validation is:
- Caught at compile time, not runtime
- Provides IDE autocompletion
- Zero runtime overhead
When to Use Runtime Validation
Use object syntax validation when:
- You're not using TypeScript
- You need to validate values that can't be expressed in types (ranges, formats)
- You want runtime debugging help during development
- You're building a component library and want helpful dev warnings
Combining Both Approaches
<script setup lang="ts">
interface FormData {
email: string;
age: number;
}
// TypeScript handles type structure
// Runtime validator handles value constraints
const emit = defineEmits({
submit: (data: FormData) => {
if (data.age < 0 || data.age > 150) {
console.warn('Age must be between 0 and 150');
return false;
}
if (!data.email.includes('@')) {
console.warn('Invalid email format');
return false;
}
return true;
},
});
</script>