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

3.4 KiB

title, impact, impactDescription, type, tags
title impact impactDescription type tags
Non-Template Content Is Implicitly Default Slot Content LOW Unexpected content placement when mixing named slots with loose content gotcha
vue3
slots
named-slots
default-slot
implicit-behavior

Non-Template Content Is Implicitly Default Slot Content

Impact: LOW - When using named slots, any top-level content not wrapped in a <template> tag is automatically treated as default slot content. This implicit behavior can cause confusion about where content will render.

Task Checklist

  • Understand that loose content goes to the default slot
  • Use explicit <template #default> when clarity matters
  • Keep slot content organization intentional

The Implicit Behavior:

<script setup>
import BaseLayout from './BaseLayout.vue'
</script>

<template>
  <BaseLayout>
    <template #header>
      <h1>Page Title</h1>
    </template>

    <!-- These are IMPLICITLY in the default slot -->
    <p>First paragraph of main content.</p>
    <p>Second paragraph of main content.</p>

    <template #footer>
      <p>Footer content</p>
    </template>
  </BaseLayout>
</template>

The two <p> elements are automatically placed in <slot> (the default slot) in the child component.

Equivalent Explicit Version:

<template>
  <BaseLayout>
    <template #header>
      <h1>Page Title</h1>
    </template>

    <!-- Explicit default slot -->
    <template #default>
      <p>First paragraph of main content.</p>
      <p>Second paragraph of main content.</p>
    </template>

    <template #footer>
      <p>Footer content</p>
    </template>
  </BaseLayout>
</template>

When Implicit Behavior Causes Confusion

Scattered Content:

<template>
  <BaseLayout>
    <template #header>
      <h1>Title</h1>
    </template>

    <p>Content A</p>  <!-- Goes to default slot -->

    <template #sidebar>
      <nav>Navigation</nav>
    </template>

    <p>Content B</p>  <!-- Also goes to default slot! -->

    <template #footer>
      <p>Footer</p>
    </template>

    <p>Content C</p>  <!-- Also goes to default slot! -->
  </BaseLayout>
</template>

All three <p> elements end up in the default slot together, which may not be the intended order or grouping.

Clearer with Explicit Default:

<template>
  <BaseLayout>
    <template #header>
      <h1>Title</h1>
    </template>

    <template #default>
      <p>Content A</p>
      <p>Content B</p>
      <p>Content C</p>
    </template>

    <template #sidebar>
      <nav>Navigation</nav>
    </template>

    <template #footer>
      <p>Footer</p>
    </template>
  </BaseLayout>
</template>

Best Practices

Scenario Recommendation
Only default slot used Implicit is fine
Mixed named + default slots Consider explicit #default
Complex layouts Always use explicit templates
Team/shared codebase Prefer explicit for clarity

The Child Component

<!-- BaseLayout.vue -->
<template>
  <div class="layout">
    <header>
      <slot name="header"></slot>
    </header>

    <aside>
      <slot name="sidebar"></slot>
    </aside>

    <main>
      <!-- All implicit content ends up here -->
      <slot></slot>
    </main>

    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

Reference