charging-cabinet/software/h5-uniapp/agent/skills/vue-best-practices/reference/emit-validation-for-complex-payloads.md
12451 b553c4e519 feat: API 统一 + 设备详情补全 + H5 导航优化
- API 路由统一: 移除 /api/h5/,统一 /api/pms/ 入口
- 二进制改名: api-server -> pms-api(与服务名一致)
- nginx: 合并 /api/ + /pms/api/ 为 /api/pms/
- 新增 docs/API.md 接口文档
- 后端: CabinetDetail 增加 rssi/pow_fail/address/soc 等字段
- Redis 管道批量读取仓体实时数据(SOC/电压/电流/功率)
- DB: 所有 TIMESTAMP 列改为 DATETIME(修复类型不匹配)
- 用户管理: 新增创建时间/修改时间列,状态改用 Switch
- 角色管理/用户管理: 操作按钮改为图标
- PC 设备详情: 基本信息补全 RSSI/ICCID/电源/地址
- PC 卡片: 通道统计改用 Lucide 图标,颜色统一
- PC 二维码: canvas 渲染,含编号文字,支持右键下载
- H5: 按 uni-app 规范修正导航(navigateTo 替代 reLaunch)
- H5: 详情页加返回导航条
- H5: 扫码支持摄像头(jsQR)+ ?id= 参数
- H5: 底部 tabBar 在所有页面常显
- H5: 首页统计改为 6 项(设备/通道/空闲/充电/充满/故障)
- H5: 下拉刷新 / 上拉加载
- 产品首页: 添加业务联系
- 文档: 清理过时文件,补充缺失规范章节
2026-07-04 04:03:02 +08:00

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
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:

<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: '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

<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