- 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: 下拉刷新 / 上拉加载 - 产品首页: 添加业务联系 - 文档: 清理过时文件,补充缺失规范章节
4.2 KiB
4.2 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| defineModel Creates Hidden Modifier Props - Avoid Naming Conflicts | MEDIUM | defineModel automatically adds hidden *Modifiers props that can conflict with your prop names | gotcha |
|
defineModel Creates Hidden Modifier Props - Avoid Naming Conflicts
Impact: MEDIUM - When using defineModel(), Vue automatically creates hidden props with the suffix Modifiers for each model. For example, a model named title will create both a title prop AND a hidden titleModifiers prop. This can cause unexpected conflicts if you have other props ending in "Modifiers".
Task Checklist
- Don't create props that end with "Modifiers" when using defineModel
- Be aware that each defineModel creates an associated *Modifiers prop
- When using multiple models, avoid names where one model could conflict with another's modifier prop
- Document custom modifiers to help consumers understand available options
Problem - Hidden props created automatically:
<script setup>
// This creates TWO props: modelValue and modelValueModifiers
const model = defineModel()
// This creates TWO props: title and titleModifiers
const title = defineModel('title')
// CONFLICT: This prop name collides with the hidden titleModifiers
const props = defineProps({
titleModifiers: Object // WRONG: Conflicts with defineModel's hidden prop
})
</script>
Parent using modifiers:
<template>
<!-- Vue passes modifiers via the hidden *Modifiers prop -->
<MyComponent v-model:title.capitalize.trim="text" />
<!-- Child receives titleModifiers = { capitalize: true, trim: true } -->
</template>
Correct - Accessing modifiers in child:
<script setup>
// Access modifiers via destructuring
const [title, titleModifiers] = defineModel('title', {
set(value) {
// Apply modifiers to the value
if (titleModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
if (titleModifiers.trim) {
value = value.trim()
}
return value
}
})
</script>
Multiple Models and Potential Conflicts
<script setup>
// These are OK - no conflicts
const name = defineModel('name') // Creates: name, nameModifiers
const age = defineModel('age') // Creates: age, ageModifiers
// PROBLEM: If you had a model named 'model', it creates:
// - 'model' prop
// - 'modelModifiers' prop
// But 'modelValue' also creates 'modelValueModifiers'!
// The names are similar and can cause confusion
// AVOID: Don't name a model something that would conflict
const model = defineModel('model') // Creates 'model' and 'modelModifiers'
// This is confusing alongside the default modelValue/modelValueModifiers
</script>
Best Practice - Clear, distinct model names:
<script setup>
// Good: Clear, distinct names that won't conflict
const firstName = defineModel('firstName') // firstNameModifiers
const lastName = defineModel('lastName') // lastNameModifiers
const email = defineModel('email') // emailModifiers
// Avoid ambiguous names
// Bad: const value = defineModel('value') // valueModifiers - too generic
// Bad: const data = defineModel('data') // dataModifiers - too generic
</script>
Documenting Custom Modifiers
When creating components with custom modifier support, document them clearly:
<script setup>
/**
* @prop {string} title - The title text
* @modifiers
* - capitalize: Capitalizes first letter
* - uppercase: Converts entire string to uppercase
* - trim: Removes leading/trailing whitespace
*/
const [title, modifiers] = defineModel('title', {
set(value: string) {
let result = value
if (modifiers.trim) result = result.trim()
if (modifiers.capitalize) {
result = result.charAt(0).toUpperCase() + result.slice(1)
}
if (modifiers.uppercase) {
result = result.toUpperCase()
}
return result
}
})
</script>
<template>
<input v-model="title" />
</template>