feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: Use Event Validation for Complex Payloads
|
||||
impact: LOW
|
||||
impactDescription: Event validation catches payload errors early with console warnings during development
|
||||
type: best-practice
|
||||
tags: [vue3, emits, defineEmits, validation, debugging]
|
||||
---
|
||||
|
||||
# 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 `defineEmits` when validation is needed
|
||||
- [ ] Return `true` for valid payloads, `false` for invalid
|
||||
- [ ] Add meaningful console warnings in validators
|
||||
- [ ] Consider TypeScript for compile-time validation instead
|
||||
|
||||
## Basic Validation
|
||||
|
||||
**Using object syntax with validators:**
|
||||
```vue
|
||||
<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
|
||||
|
||||
```vue
|
||||
<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
|
||||
```vue
|
||||
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
|
||||
```vue
|
||||
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
|
||||
```vue
|
||||
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:
|
||||
|
||||
```vue
|
||||
<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: 'test@test.com' })
|
||||
// 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
|
||||
|
||||
```vue
|
||||
<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>
|
||||
```
|
||||
|
||||
## Reference
|
||||
- [Vue.js Component Events - Events Validation](https://vuejs.org/guide/components/events.html#events-validation)
|
||||
Reference in New Issue
Block a user