- 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
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Use Debug Hooks to Trace Reactivity Issues | MEDIUM | Debug hooks help identify which dependencies trigger re-renders and watcher executions | efficiency |
|
Use Debug Hooks to Trace Reactivity Issues
Impact: MEDIUM - Vue provides debug hooks (onTrack, onTrigger, renderTracked, renderTriggered) that help identify exactly which reactive dependencies are being tracked and which mutations trigger re-execution. These are invaluable for debugging performance issues and unexpected re-renders.
Debug hooks only work in development mode and are stripped in production builds. Use them to understand why a computed property, watcher, or component is re-executing.
Task Checklist
- Use
onTrackandonTriggeroptions on computed/watch for granular debugging - Use
onRenderTrackedandonRenderTriggeredlifecycle hooks for component render debugging - Add
debuggerstatements inside hooks to pause execution and inspect state - Remove or comment out debug hooks before production (they're no-ops but add clutter)
Note:
onTrackandonTriggerare development-only hooks. They are stripped from production builds and may not fire in test environments (e.g., Vitest, Jest) depending on how Vue is bundled. If you need to verify reactivity behavior in tests, use direct assertions on reactive state changes rather than relying on these debug callbacks.
Debugging computed properties:
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2, {
onTrack(event) {
// Called when a dependency is tracked
// event.target = the reactive object
// event.key = the property being accessed
debugger
console.log('Tracking:', event)
},
onTrigger(event) {
// Called when a dependency mutation triggers re-computation
debugger
console.log('Triggered by:', event)
}
})
Debugging watchers:
import { ref, watch, watchEffect } from 'vue'
const source = ref(0)
// With watch()
watch(source, (newVal, oldVal) => {
console.log('Changed:', oldVal, '->', newVal)
}, {
onTrack(e) {
debugger // Pause to see what's being tracked
},
onTrigger(e) {
debugger // Pause to see what triggered the watcher
}
})
// With watchEffect()
watchEffect(() => {
console.log('Source is:', source.value)
}, {
onTrack(e) {
console.log('Tracking dependency:', e.key)
},
onTrigger(e) {
console.log('Triggered by:', e.key, 'mutation')
}
})
Debugging component renders:
<script setup>
import { onRenderTracked, onRenderTriggered, ref } from 'vue'
const count = ref(0)
// Called for every reactive dependency accessed during render
onRenderTracked((event) => {
console.log('Render tracked:', event.key, 'from', event.target)
debugger // Pause to inspect which dependencies are tracked
})
// Called when a reactive dependency triggers re-render
onRenderTriggered((event) => {
console.log('Render triggered by:', event.key)
console.log('Old value:', event.oldValue)
console.log('New value:', event.newValue)
debugger // Pause to see exactly what caused the re-render
})
</script>
Options API equivalent:
export default {
data() {
return { count: 0 }
},
renderTracked(event) {
console.log('Dependency tracked during render:', event)
debugger
},
renderTriggered(event) {
console.log('Re-render triggered by:', event)
debugger
}
}
Debug event properties:
// The event object contains:
{
effect: ReactiveEffect, // The effect being debugged
target: object, // The reactive object
type: 'get' | 'set' | 'add' | 'delete' | 'clear',
key: string | symbol, // The property being accessed/mutated
oldValue: any, // Previous value (for onTrigger)
newValue: any // New value (for onTrigger)
}