# 15 - UI 设计规范与交互原则(DataTool) > 本文作为 DataTool 项目前端的统一 UI 设计规范与交互基线,后续所有功能开发应在不违背本规范的前提下扩展。若有必要变更,请同步更新本文件。 --- ## 1. 产品定位与使用场景 - **产品类型**:轻量级、基于浏览器的数据传输工具 - **核心场景**:在 VNC / 远程桌面 / 内网隔离等环境中,通过 6 位房间号在多端之间快速传文本、文件、图片和剪贴板内容 - **受众角色**:开发 / 运维 / 支持工程师、内网用户 - **体验方向**:**稳定、可靠、低干扰、专业、轻量** --- ## 2. 整体设计原则 - **一致性优先** - 所有页面沿用统一的色板、字体、圆角与阴影体系。 - 所有按钮、输入框、消息卡片、文件卡片必须复用同一套组件样式,不允许在局部自行定义“新样式”。 - **信息层次清晰** - 强调房间号与连接状态,其次是消息内容与文件进度,最后是系统提示和辅助信息。 - 使用颜色 / 字号 / 粗细 / 间距来区分重要程度,避免靠纯颜色或纯位置。 - **状态可感知** - WebSocket 连接状态、房间加入/退出、文件发送与接收进度必须在 UI 中可见且明确。 - 所有异步操作(发送消息、上传文件、读取剪贴板等)都有“进行中 / 成功 / 失败”的视觉反馈。 - **轻量与性能** - 大量消息场景下保持滚动流畅,避免复杂阴影和高成本动画。 - 组件优先考虑简单、可扩展的布局,预留虚拟列表等性能优化空间。 - **可访问与可维护** - 遵守基本对比度、可聚焦与键盘可操作性。 - 使用统一的设计 token(颜色/间距/字号),便于全局调整。 --- ## 3. 视觉设计规范 ### 3.1 色彩体系(建议映射到 CSS 变量 / Tailwind token) - **品牌主色(Primary)** - 基准色:`#2563EB`(蓝,类似 Tailwind `blue-600`) - Hover:`#1D4ED8`(`blue-700`) - Active:`#1E40AF`(`blue-800`) - 主要用于:主按钮、主操作高亮、房间号强调、连接状态“已连接”标识。 - **强调色(Success / Danger / Warning)** - Success:`#16A34A`(`green-600`)—— 文件传输完成、连接成功、操作成功提示。 - Danger:`#DC2626`(`red-600`)—— 错误、连接失败、限制触发。 - Warning:`#F97316`(`orange-500`)—— 限制接近阈值、网络不稳定等。 - **中性色(背景 / 边框 / 文本)** - 页面背景:`#F8FAFC`(`slate-50`) - 卡片背景:`#FFFFFF` - 边框:`#E2E8F0`(`slate-200`) - 分割线:`#E5E7EB`(`gray-200`) - 主文本:`#0F172A`(`slate-900`) - 次级文本:`#475569`(`slate-600`) - 弱化文本/占位:`#9CA3AF`(`gray-400`)及以上,不使用更浅灰值作为正文。 - **系统消息与提示色** - 系统消息背景:`#EFF6FF`(`blue-50`),文字使用 `#1D4ED8`。 - 提示条(Banner):背景 `#F1F5F9`(`slate-100`),根据状态加左侧色条(蓝/绿/橙/红)。 > 所有新页面不得新增“第二主色”,若确有需要,先在本文件补充“辅助色(Secondary)”章节再使用。 ### 3.2 字体与排版 - **字体族** - 优先:`system-ui, -apple-system, BlinkMacSystemFont, "SF Pro SC", "PingFang SC", "Microsoft YaHei", sans-serif` - **字号层级(桌面端基线)** - 标题 H1:24px / 32px,用于页面主标题(如“房间 123456”) - 标题 H2:20px / 28px,用于分区标题(在线用户、消息区、文件传输) - 标题 H3:16px / 24px,用于小模块标题、卡片标题 - 正文:14px / 22px(首选),行高 1.6 - 标签/次要信息:12px / 18px,谨慎使用,保证可读性 - **文字对齐** - 文本与输入框左对齐,数字型信息(如进度百分比)可以右对齐。 - **行宽与段落** - 文本区域最大宽度建议控制在 65–75 个汉字以内,避免极长单行。 ### 3.3 圆角、阴影与描边 - **圆角** - 输入框/按钮:`4px` - 卡片(消息卡片、文件卡片):`8px` - 悬浮面板 / 弹窗:`12px` - **阴影** - 默认卡片:无阴影,仅边框(`border-slate-200`) - 悬浮/高层级元素(如弹窗、悬浮面板):轻量阴影 `0 10px 25px rgba(15,23,42,0.08)` - **描边** - 主按钮:默认无边框,仅用色块;Hover 时可增加内阴影或细微深色。 - 输入框:有 1px 描边,聚焦时描边色切换为主色并增加轻微光晕。 ### 3.4 间距与栅格 - 页面左右内边距:桌面端 `24px`,窄屏端 `16px` - 区块间距(模块与模块之间):`24px` - 元素垂直间距(标题与内容 / 行与行):`8–12px` - 列表项内边距:上下 `8px` / 左右 `12px` - 使用 4 的倍数作为统一间距刻度:`4 / 8 / 12 / 16 / 24 / 32` --- ## 4. 布局与信息架构 ### 4.1 整体布局结构 - **桌面端(≥ 1024px)** - 顶部:窄高度顶部栏,包含项目 Logo/名称、当前房间号、连接状态指示、小范围操作(帮助、设置)。 - 主区:左右双栏布局。 - 左侧(约 25–30% 宽度):`RoomPanel`,包含房间信息、在线用户列表、基础操作(退出、清空、导出)。 - 右侧(约 70–75% 宽度):消息与文件显示区域(消息列表 + 文件/图片预览),底部为输入与文件操作区域。 - **窄屏端(< 1024px)** - 顶部栏保留,主内容上下布局: - 默认展示消息区域,在线用户通过折叠面板或底部抽屉查看。 - 拖拽上传在窄屏上使用明显的上传按钮 + 粘贴提示,拖拽仅作为增强能力。 ### 4.2 关键页面说明 - **首页 `HomeView`** - 中心内容区居中显示: - 左:创建房间卡片(展示自动生成 6 位房间号 + “创建并进入”按钮) - 右:加入房间卡片(房间号输入框 + 加入按钮) - 明确提示“数据不落库 / 仅当前会话可见”等安全特性(简短描述)。 - 若已有最近加入的房间记录,可在下方列出“最近使用的房间”列表(历史记录相关)。 - **房间页 `RoomView`** - 顶部显示: - 房间号(可点击复制)+ 小标签(如“临时房间”) - 连接状态:圆点 + 文本(连接中/已连接/断开/重连中) - 左侧 `RoomPanel`: - 在线用户列表(昵称 + 状态点),当前用户行高亮。 - 简要统计信息:在线人数、当前传输中文件数量等。 - 操作按钮:退出房间(弱化但明确)、清空本地历史、导出历史。 - 右侧主区: - 上方:消息与系统提示列表(含文本、图片、文件卡片、SYSTEM 消息)。 - 下方:输入区域(文本输入 + 发送按钮 + 附件/文件按钮 + 剪贴板按钮)。 ### 4.3 消息列表布局 - **文本消息** - 根据发送者区分左右对齐(可选),也可统一左对齐,通过头像首字母+昵称区分。 - 时间戳放置在右下角,使用次级文字色。 - **系统消息** - 居中对齐,使用浅色条带样式,与普通消息明显区分。 - 内容如“xxx 加入房间 / 离开房间 / 连接已重连”等。 - **文件与图片消息** - 使用卡片样式,包含文件名、大小、进度条、状态图标以及操作按钮(下载/打开)。 --- ## 5. 核心组件规范 > 实现时建议将以下元素封装为 Vue 组件,并在使用前优先复用。 ### 5.1 按钮(`Button`) - **尺寸** - 大:高度 40–44px(主要操作,如“创建房间”“加入房间”“发送”) - 中:高度 32–36px(列表操作、弹窗确认等) - 小:高度 28–32px(标签型按钮、图标按钮) - **类型** - 主按钮(Primary):填充主色,白色文字,圆角 4px。 - 次按钮(Secondary):白底 + 主色描边 + 主色文字。 - 危险按钮(Danger):红色填充 + 白色文字,仅用于删除/退出等操作。 - 文本按钮(Ghost/Text):透明背景 + 主色文字,用于低权重操作。 - **状态** - 默认 / Hover / Active / Disabled 四态。 - Hover:亮度 + 边框/阴影轻微变化,不允许大幅缩放导致布局抖动。 - Disabled:降低对比度并移除悬浮态,鼠标指针改为默认。 ### 5.2 输入与表单(`Input`, `Textarea`, `FormField`) - **样式** - 高度 36–40px,左右有 12–16px 内边距。 - 边框颜色:默认 `#E2E8F0`,聚焦 `primary`。 - 占位文字使用 `gray-400`,不可与正常正文颜色相同。 - **校验** - 房间号输入框限制为 6 位数字,错误时在输入框下方展示红色错误文案,并将边框颜色切换为 `red-500`。 - 提交按钮在校验不通过时为禁用状态。 ### 5.3 标签与状态(`Tag`, `Badge`, `StatusDot`) - 用于表示连接状态、房间类型、文件状态等。 - 状态点尺寸 8–10px,放置在用户名左侧或右上角。 - 颜色与状态映射保持统一(如:绿色=在线,灰色=离线,橙色=异常)。 ### 5.4 消息气泡与系统消息(`MessageItem`, `SystemMessage`) - 消息气泡: - 背景使用白色或略带浅灰,边框微弱(可选)。 - 内部包含:昵称(可选)/ 消息内容 / 时间戳。 - 系统消息: - 使用全宽度条带,背景为 `blue-50` 或 `slate-100`,文字居中。 - 与气泡在视觉上区分开(不使用“对话气泡”样式)。 ### 5.5 文件卡片与进度条(`FileMessage`, `ProgressBar`) - **文件卡片内容** - 文件名(可省略中间,用省略号显示)+ 文件大小 + 文件类型图标。 - 进度条(发送端、接收端皆可见)+ 状态标签(传输中 / 已完成 / 失败)。 - 操作按钮:下载、打开所在文件夹(浏览器可行范围内)、重新下载(失败时)。 - **进度条样式** - 高度 4–6px,圆角 999px。 - 背景条颜色 `slate-200`,前景条使用主色或状态色。 ### 5.6 图片预览卡片(`ImageMessage`, `ImagePreviewModal`) - 消息列表中展示缩略图(固定宽高比,如 4:3),点击后打开大图预览。 - 大图使用居中遮罩弹窗,背景半透明黑色,支持点击空白处关闭或 Esc 关闭。 ### 5.7 Toast 与通知(`Toast`, `AlertBanner`) - Toast 适合短暂状态提示(发送成功、复制成功),出现在右上角或右下角,自动消失。 - AlertBanner 适合持久的提醒(当前使用 HTTP 协议、传输大小接近上限等),固定在内容区顶部。 --- ## 6. 关键交互流程规范 ### 6.1 加入 / 创建房间 - **创建房间** - 点击“创建房间”后立即显示加载状态(按钮禁用 + Loading 图标)。 - 创建成功后自动跳转到房间页,并以系统消息提示“你已创建并进入房间 123456”。 - **加入房间** - 用户输入 6 位房间号,实时校验;不足 6 位或包含非数字字符时按钮禁用。 - 加入失败(房间不存在/连接错误)时: - 在输入框下方显示清晰错误文案。 - 可用 Toast 或 Banner 补充说明。 ### 6.2 WebSocket 连接与状态恢复 - 顶部栏右上区域固定显示连接状态: - 连接中:黄色点 + “连接中…” - 已连接:绿色点 + “已连接” - 重连中:橙色点 + “重连中…” - 已断开:红色点 + “已断开” - 当状态从“断开/重连中”恢复到“已连接”时: - 插入一条 SYSTEM 消息说明“已重新连接,已重新加入房间”。 ### 6.3 消息发送与错误处理 - 按下 Enter 发送消息,Shift+Enter 换行(在文本框旁明确提示)。 - 发送过程中,发送按钮进入 Loading 状态并禁用,避免重复点击。 - 若发送失败(网络中断等): - 消息在列表中使用“失败”样式(如左侧红色竖线 + 灰度文字)。 - 提供“重试发送”小按钮。 ### 6.4 文件拖拽上传 / 粘贴 - **拖拽区域** - 在输入区域上方或消息列表顶部提供明显的拖拽提示区域(浅虚线边框 + 上传图标)。 - 拖拽文件进入页面时,高亮整个拖拽区域,并在靠顶部位置显示提示条(如“释放鼠标以发送文件到房间 123456”)。 - **粘贴文件 / 剪贴板** - 当用户使用 Ctrl+V 粘贴文件或图片时,提示一次确认(可选):“是否将剪贴板中的图片/文件发送到当前房间?”。 - 剪贴板权限被浏览器限制时,弹出说明性对话框,引导用户手动拖拽或选择文件。 ### 6.5 历史记录与本地存储 - 在房间页的 `RoomPanel` 中提供“历史记录”入口,可选择: - 清空当前房间历史(弹出确认对话框)。 - 导出当前房间历史(文件命名建议:`DataTool-房间号-时间戳.json`)。 - 刷新页面后自动加载当前房间的本地历史,并通过淡入动画呈现。 --- ## 7. 可访问性与通用 UX 要求 - **颜色对比度** - 正文文本与背景对比度 ≥ 4.5:1,次级文本不低于 3:1。 - **键盘导航** - 所有按钮和可点击卡片必须可通过 Tab 聚焦,按 Enter/Space 触发。 - 焦点样式清晰可见(外发光或描边),不依赖颜色变化微弱的 hover 效果。 - **ARIA 与语义化** - 图标按钮(仅图标无文字)添加 `aria-label`。 - 使用语义标签(`
`, `
`, `