# 设置面板 UI 改进总结 ## 问题修复 ### 1. 保存后未立即生效 ✅ **原因分析:** - `tabs` 数组中的 `visible` 属性与 `visibleTabs` 数组不同步 - `watch(selectedTabs)` 覆盖了拖拽排序的顺序 **修复方案:** 1. 在 `handleTabVisibilityChange` 中同步更新 `tabs` 数组的 `visible` 属性 2. 移除 `watch(selectedTabs)`,避免覆盖排序 3. 在 `handleSave` 中确保数据完全同步 4. 在 `loadConfig` 中从后端加载时同步 `visible` 属性 ### 2. UI 合并优化 ✅ **改进前:** - Tab 显示、默认 Tab、拖拽排序分成三个独立的卡片 - 用户需要在不同区域操作,不够直观 **改进后:** - 统一到一个列表中,每行包含所有控制项 - 更直观、更高效的配置体验 ## 新的 UI 设计 ### Tab 配置列表结构 ``` ┌─────────────────────────────────────────────────────┐ │ ℹ️ 拖拽可调整 Tab 顺序,勾选复选框控制显示,单选按钮 │ │ 设置默认打开的 Tab │ ├─────────────────────────────────────────────────────┤ │ ⋮ ☑ 数据库 ○ 默认打开 │ │ ⋮ ☑ 文件管理 ○ 默认打开 │ │ ⋮ ☑ 设备调用测试 ⦿ 默认打开 │ ├─────────────────────────────────────────────────────┤ │ 隐藏的 Tabs │ ├─────────────────────────────────────────────────────┤ │ ⋮ ☐ (其他隐藏的 Tab) │ └─────────────────────────────────────────────────────┘ ``` ### 每行包含的元素 1. **拖拽手柄** (⋮) - 拖拽调整顺序 2. **复选框** (☑/☐) - 控制显示/隐藏 3. **Tab 标题** - 显示 Tab 名称 4. **单选按钮** (⦿) - 设置默认打开的 Tab ## 技术实现 ### 新增辅助函数 ```javascript // 判断 Tab 是否可见 const isTabVisible = (key) => { return localConfig.value.visibleTabs.includes(key) } // 判断 Tab 是否启用 const isTabEnabled = (key) => { const tab = localConfig.value.tabs.find(t => t.key === key) return tab ? tab.enabled : false } // 隐藏的 Tabs 计算属性 const hiddenTabs = computed(() => { return localConfig.value.tabs.filter( tab => !localConfig.value.visibleTabs.includes(tab.key) ) }) ``` ### 改进的可见性处理 ```javascript // 处理单个 Tab 可见性变化 const handleTabVisibilityChange = (tabKey, visible) => { if (visible) { // 显示 Tab:添加到 visibleTabs 末尾 localConfig.value.visibleTabs.push(tabKey) } else { // 隐藏 Tab:从 visibleTabs 中移除 // 至少保留一个 Tab if (localConfig.value.visibleTabs.length <= 1) { Message.warning('至少需要保留一个可见的 Tab') return } // 如果隐藏的是默认 Tab,需要更改默认 Tab if (localConfig.value.defaultTab === tabKey) { const remainingTabs = localConfig.value.visibleTabs.filter(k => k !== tabKey) localConfig.value.defaultTab = remainingTabs[0] || '' } localConfig.value.visibleTabs = localConfig.value.visibleTabs.filter( k => k !== tabKey ) } // 同步更新 tabs 数组中的 visible 属性 localConfig.value.tabs = localConfig.value.tabs.map(tab => ({ ...tab, visible: localConfig.value.visibleTabs.includes(tab.key) })) } ``` ### 保存前数据同步 ```javascript // 保存配置 const handleSave = async () => { // ... 验证逻辑 ... // 确保 tabs 数组中的 visible 属性与 visibleTabs 完全同步 const syncedTabs = localConfig.value.tabs.map(tab => ({ ...tab, visible: localConfig.value.visibleTabs.includes(tab.key) })) const configToSave = { tabs: syncedTabs, visibleTabs: [...localConfig.value.visibleTabs], defaultTab: localConfig.value.defaultTab } // ... 保存逻辑 ... } ``` ## 样式改进 ### 配置项样式 ```css .tab-config-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: var(--color-fill-1); border: 1px solid var(--color-border); border-radius: 6px; cursor: move; transition: all 0.2s; } .tab-config-item:hover { background: var(--color-fill-2); border-color: var(--color-border-2); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .tab-config-item.dragging { opacity: 0.5; background: var(--color-fill-2); transform: scale(0.98); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } ``` ### 隐藏项样式 ```css .tab-config-item.hidden { opacity: 0.6; cursor: default; } .tab-config-item.hidden:hover { border-color: var(--color-border); box-shadow: none; } ``` ## 用户体验改进 1. **一目了然** - 所有配置集中在一行,无需来回查看 2. **即时反馈** - 拖拽时有视觉反馈(透明度、缩放、阴影) 3. **智能提示** - 顶部说明文字告知用户如何操作 4. **分组显示** - 可见和隐藏的 Tab 分开展示 5. **保护机制** - 至少保留一个可见 Tab,最后一个 Tab 的复选框禁用 ## 数据流保证 ### 配置加载 ``` 后端 → GetAppConfig → loadConfig → 同步 visible 属性 → 显示 ``` ### 配置保存 ``` 用户操作 → localConfig → handleSave → 同步数据 → 后端保存 → 刷新 UI ``` ### 关键同步点 1. **复选框改变** → 同步 `visibleTabs` 和 `tabs[].visible` 2. **拖拽排序** → 更新 `visibleTabs` 顺序 3. **保存前** → 确保所有 `visible` 属性与 `visibleTabs` 一致 4. **加载后** → 根据后端数据同步 `visible` 属性 ## 测试清单 ### 基础功能 - ✅ 拖拽排序 Tab - ✅ 勾选/取消勾选复选框 - ✅ 设置默认 Tab - ✅ 保存配置后立即生效 - ✅ 刷新页面后配置保持 ### 边界情况 - ✅ 至少保留一个可见 Tab - ✅ 隐藏默认 Tab 时自动切换 - ✅ 禁用的 Tab 不可操作 - ✅ 配置为空时显示默认值 ### UI 交互 - ✅ 拖拽时视觉反馈 - ✅ hover 状态提示 - ✅ 隐藏项分组显示 - ✅ 说明文字清晰 ## 修复文件 - `frontend/src/components/SettingsPanel.vue` - UI 合并和逻辑修复 - `frontend/src/App.vue` - loadConfig 和 handleSaveConfig 数据同步 ## 总结 本次改进解决了两个主要问题: 1. **保存后未立即生效** - 通过数据同步机制修复 2. **UI 不够直观** - 通过统一配置列表优化 用户体验得到显著提升,配置操作更加高效和直观。