本地面板应优先用 localstorage 保存场景状态实现即时 ui 反馈,通过 data-scene-id 统一标识、css 自定义属性驱动视觉效果、grid 布局适配多端,并建立设备状态字段映射层。

用 localStorage 保存场景状态,别依赖后端接口
多数人一上来就想连 MQTT 或调 API,但本地面板的核心诉求是「点一下就变灯色/开关空调」,响应必须快。真实场景里,设备状态常滞后或断连,用户要的是视觉即时反馈——所以先改 UI,再异步同步设备。
用 localStorage 记录当前激活的场景(比如 "scene:living_room_night"),页面加载时读取并高亮对应按钮。这样刷新不丢状态,也不卡顿。
- 不要在
DOMContentLoaded里等设备查询完成才渲染按钮,先按缓存值设class="active" - 切换场景时,立刻更新 DOM 和
localStorage,再用fetch()或 WebSocket 发指令;失败了再回滚 UI + 提示 - 注意 Safari 的无痕模式会拒绝
localStorage,加个 try/catch 回退到内存变量
data-scene-id 统一标识场景,别用 class 名硬编码
写死 class="scene-living-night" 看似简单,但后期加新场景、改名、做国际化时,JS 里一堆字符串匹配和 CSS 里重复声明,极易漏改。用自定义属性才是可维护的做法。
每个场景按钮写成:<button data-scene-id="living_night">客厅夜模式</button>,JS 里统一用 dataset.sceneId 读取。
- 所有场景 ID 小写+下划线,避免空格或大写导致 JS 获取异常
- CSS 选中样式写成
[data-scene-id="living_night"].active,不耦合 class 名 - 生成按钮时从 JSON 配置数组循环渲染,ID、文案、图标都来自数据,不是 HTML 里手敲
用 CSS custom properties 控制灯光/窗帘等模拟效果
纯 HTML 面板不需要真控硬件,但用户需要感知“这个场景生效了”。靠颜色块、进度条、旋转图标就能建立心理模型——而这些完全可用 CSS 变量驱动,无需 JS 操作 style。
例如定义::root { --light-brightness: 100%; --curtain-open: 0%; },然后灯光 div 写 opacity: var(--light-brightness);,窗帘条用 transform: scaleY(var(--curtain-open));。
- 每次切换场景,JS 只需执行
document.documentElement.style.setProperty('--light-brightness', '30%') - 避免用
classList.add('dim')这类多 class 方案,状态组合爆炸(亮+开+冷色)难维护 - 动画用
transition: opacity 0.3s, transform 0.4s,别用 JS 帧动画,耗电且卡
响应式布局用 grid-template-areas,别堆 float 或 inline-block
面板要在手机、平板、桌面都清晰可点,尤其老人常用大号字体+触控。浮动布局在字号缩放后容易错行,inline-block 有空白符间隙问题,直接上 CSS Grid 的命名区域最稳。
比如定义:grid-template-areas: "lamp ac scene" "curtain curtain scene";,每个设备区域用 area 属性对齐,缩放时自动重排。
- 手机竖屏时用媒体查询改成
"lamp" "ac" "curtain" "scene"单列 - 按钮最小尺寸设
min-width: 120px; min-height: 60px,防误触 - 禁用
user-select: none,否则 iOS 上长按可能触发复制菜单干扰操作
brightness、level 或 dimming,而你的面板只认 --light-brightness。这个映射层得提前设计好,不然后面每接一个新设备都要翻修 UI 逻辑。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











