移动端设计语言与 Varlet 降级决议
状态: Accepted v4.2 作者: miaotouy / 咕咕 / Codex 日期: 2026-06-09 前提: 移动端尚未对外发布,仍处于内部构建阶段,无线上兼容性债务
版本演进
| 版本 | 核心命题 | 状态 |
|---|---|---|
| v1 | 把"玻璃质感"当作 AIO Hub 的 DNA | 错判 |
| v2 | DNA 修正为"高度可定制视觉系统 + 品牌一致性元素",但仍在"换不换 UI 库"的框架里讨论 | 不彻底 |
| v3 | 跳出"UI 库选型"框架,提出组件抽象层路线,但直接把自研 base/ 写成既定结论 | 武断 |
| v3.1 | 修正为"先组件适配性调查,再决定 Varlet 降级范围" | 已被 v4 覆盖 |
| v4 | 直接决议:Varlet 降级为底层组件库。移动端整体仍以 Vue 原生组件、项目 CSS token 和业务自研骨架为主 | 已被 v4.1 覆盖 |
| v4.1 | 补充 AIO Hub 产品定位:不是传统小工具合集,而是在统一框架下承载复杂能力、降低使用门槛的工具枢纽 | 已被 v4.2 覆盖 |
| v4.2 | 修正 §3/§5 的"照搬桌面端组件清单"问题,改为需求驱动式沉淀 | 当前版本 |
0. 当前决议
这次不再继续围绕"Varlet 是否适合承担移动端框架"做开放式调查。实际体验已经给出结论:
Varlet 的默认设计语言和主题气质不适合作为 AIO Hub Mobile 的整体框架。 它可以留下来,像桌面端的 Element Plus 一样提供底层组件能力;但不能继续决定移动端页面骨架、主题表现、容器语义和默认审美。
移动端的新定位:
Tauri v2 + Vue 3 + TypeScript + Rust
├─ AIO Hub 自有主题 token / 质感系统 / 品牌细节
├─ Vue 原生组件与业务组件承担页面骨架
├─ mobile/src/components/common 沉淀跨工具通用组件
├─ mobile/src/components/base/ 沉淀移动端基础容器与交互骨架
└─ Varlet 仅作为可替换的底层组件库一句话:移动端是 AIO Hub 的 Vue/Tauri 移动实现,不是 Varlet/MD3 应用。
同时需要修正一个容易误导后续设计的表述:AIO Hub 不是纯粹的"小工具集合",也不是只面向强专业用户的冷硬工具箱。桌面端很多功能已经在持续做两件事:一是把复杂能力装进更顺手的交互里,降低用户理解和使用成本;二是在统一的工具框架下,让新能力可以快速开发、注册和接入,甚至不需要反复改路由和主框架。
因此,移动端不应把自己设计成"一个木函"、"图吧工具箱"这类传统工具合集的移动复刻。它更接近一个可扩展的 AI 工具枢纽:既允许单个工具轻量接入,也允许像桌面端 Chat 那样成长为完整、强大的系统级能力。
1. 设计 DNA
1.1 默认形象
桌面端默认状态的真实气质是:
| 维度 | 桌面端默认 |
|---|---|
| 背景 | 纯色,跟随明暗主题 |
| UI 层 | 不透明卡片,无默认玻璃 |
| 主题色 | #409eff Element Plus 蓝 |
| 状态色 | 绿 / 橙 / 红 / 灰,克制工具色板 |
| 边框 | 1px 标准实线 |
| 圆角 | 中等克制 |
| 头像 | 圆角矩形,非圆形 |
| 图标 | Lucide 线性图标 |
| 布局 | 信息密度较高,但强调顺手、连续、可理解的工作流 |
移动端允许更适合触屏的间距、字号和单栏流程,但默认气质不应被收窄成"严肃专业的小工具箱"。它应是干净、可靠、上手成本低、能承载复杂能力的 AIO Hub 工具枢纽:轻量工具可以快速并入,复杂工具也能拥有完整体验;不是 Material Design 模板应用,也不是一套 Varlet 主题样板。
1.2 高定制态
质感系统是 AIO Hub 的能力,而不是默认妆效:
- 壁纸基底
- 半透明层
backdrop-filter: blur(var(--ui-blur)- 主题色自动取色
- 卡片/弹层/导航透明度分层
- 性能降级策略
移动端后续应移植这套能力,但默认不把玻璃、MD3 动态色或 Varlet 主题当作产品识别本身。
1.3 架构 DNA
桌面端的真实分层是:
页面骨架 / 业务容器 / 复杂交互 -> 自研 Vue 组件
通用能力组件 -> src/components/common/
按钮 / 输入 / 选择等原子件 -> Element Plus
命令式消息与弹窗 -> customMessage / BaseDialog 等项目封装这套分层的价值不只是"组件自研"或"看起来统一",更重要的是让功能开发可以无痛并入统一框架:工具按 registry 接入,页面和服务能力按约定组织,主应用不为每个新工具反复改动路由和骨架。移动端应该继承的是这种可扩展产品框架,而不是把所有能力压平成松散入口列表。
移动端应对齐这套思想:
页面骨架 / 工具容器 / 移动交互 -> 自研 Vue 组件
移动端基础组件 -> mobile/src/components/base/
跨工具通用组件 -> mobile/src/components/common/
按钮 / 输入 / 选择等原子件 -> Varlet 可用但不主导
命令式消息与弹窗 -> customMessage / customDialog 项目封装2. Varlet 新定位
2.1 可以保留的范围
Varlet 可以继续用于:
var-buttonvar-inputvar-selectvar-switchvar-slidervar-checkboxvar-radiovar-chip- `var-loading其他低风险、叶子节点级组件
Snackbar/Dialog的底层实现,但必须经项目封装后调用
这些组件的角色与桌面端的 <el-button>、<el-input>、<el-select> 类似:省实现成本,但不定义产品骨架。
2.2 不应继续承担的范围
以下组件不应作为新增页面或重构后的主结构来源:
var-app-barvar-popupvar-cellvar-cardvar-papervar-bottom-navigationvar-style-provider对项目主题的主导权
已有代码可以渐进迁移,但新增代码不要继续扩大这些组件的结构性占比。
2.3 命令式 API
业务代码不应继续散落:
import { Snackbar, Dialog } from "@varlet/ui";目标是统一替换为:
import { customMessage } from "@/utils/customMessage";
import { customDialog } from "@/utils/customDialog";底层仍可调用 Varlet,但调用点必须收敛,API 与桌面端习惯对齐。
3. 目标分层
3.1 目录结构
mobile/src/
├── components/
│ ├── base/ # 按需沉淀,不预设清单
│ ├── common/ # 按需沉淀,不照搬桌面端
│ │ ├── DynamicIcon.vue # 已有:工具图标渲染需要
│ │ ├── IconPresetSelector.vue # 已有:llm-api 图标选择需要
│ └── (后续按实际需求增长)
│ └── AppBottomNav.vue
├── tools/
│ └── {toolId}/
│ ├── views/
│ ├── components/
│ └── {toolId}.registry.ts
├── stores/
│ └── theme.ts # 输出 AIO token,兼容写入 Varlet 变量
└── utils/
├── customMessage.ts
├── customDialog.ts├── errorHandler.ts
├── logger.ts
└── ...3.2 沉淀原则
组件沉淀采用需求驱动,不采用"对照桌面端清单预建":
base/: 当某个 Varlet 容器组件确实在多处造成气质问题或定制困难时,才提取对应的 Base 组件。不预设完整清单,不要求一口气补齐。common/: 当某个功能(如头像、文件图标等)在两个以上工具中出现实际需求时,才沉淀通用组件。桌面端有的组件可以作为设计参考,但移动端实现应基于移动端自身的场景和交互模式重新设计,不是代码搬运。
3.3 已知的未来需求(参考,非硬性清单)
以下组件在移动端功能扩展过程中大概率会需要,但具体实现时机和形态应由实际场景决定:
| 组件 | 触发条件 | 备注 |
|---|---|---|
| Avatar | Chat 功能完善、用户档案系统接入时 | 按移动端场景重新设计,不照搬桌面端 |
| BaseAppBar | 当 var-app-bar 的样式限制成为多页面痛点时 | 目前 var-app-bar 基本够用 |
| BaseSheet | 当 var-popup 无法满足自定义需求时 | 目前 var-popup 用着还行 |
| BaseListItem | 当 var-cell 在设置页的气质/定制问题频繁出现时 | 这是当前使用最密集的容器组件(40+ 处) |
4. 主题规则
4.1 主从关系
主题主从关系必须明确:
AIO Hub token -> 移动端 Vue/CSS 组件 -> Varlet 兼容变量不能倒过来:
Varlet / MD3 token -> AIO Hub 主题4.2 必备项目 token
移动端至少应稳定维护下列项目级变量:
| 类型 | 变量示例 |
|---|---|
| 品牌色 | --primary-color |
| 状态色 | --success-color / --warning-color / --danger-color / --info-color |
| 背景 | --bg-color / --card-bg / --container-bg / `--input |
| 文本 | --text-color / --text-secondary-color |
| 边框 | --border-color / --border-width |
| 圆角 | --app-radius-sm / --app-radius-md / --app-radius-lg |
| 质感 | --ui-blur / --card-opacity |
| 安全区 | --app-safe-area-top / --app-top-offset |
Varlet 变量只能作为适配输出,用于让保留的 var-* 原子件不突兀。
4.3 视觉禁区
- 不要把 Material Design 3 当作移动端视觉基准。
- 不要让大面积
var-card/var-paper形成统一的 Varlet 味。 - 不要用 Varlet 默认圆角、阴影、surface 分层决定 AIO 的默认观感。
- 不要把
StyleProvider的主题输出当成唯一主题源。
5. 迁移路线
核心原则
迁移不按"先造组件库再替换"的顺序执行。正确的驱动力是:哪里痛就先动哪里,在动的过程中按需沉淀 base/common 组件。
桌面端的通用组件(Avatar、BaseDialog 等)都是在实际功能开发中被逼出来的,移动端也应该走同样的路径。
Phase 0:规范落地(已完成)
- 更新
AGENTS.md,明确移动端 UI 分层。 - 同步修正"专业工具箱 / 小工具合集"式描述。
- 将本文件作为移动端设计语言的当前决议。
Phase 1:收敛命令式 API
- 建立
mobile/src/utils/customMessage.ts,包装 VarletSnackbar。 - 建立
mobile/src/utils/customDialog.ts,包装 VarletDialog。 - 替换业务代码里散落的
Snackbar/Dialog直接调用。 - 底层仍用 Varlet,但业务层只看项目 API。
Phase 2+:需求驱动的渐进迁移
不预设固定的 Phase 2/3/4/5 顺序。以下是可能的迁移方向,按实际开发中碰到痛点时触发:
气质层面(视觉主导权):
- 当
var-cell在设置页面的样式覆盖越来越痛时 → 提取BaseListItem - 当
var-app-bar限制了顶部栏的品牌表达时 → 提取BaseAppBar - 当
var-popup无法满足弹层定制需求时 → 提取BaseSheet
功能层面(新功能驱动):
- 当 Chat 完善到需要自定义头像体系时 → 按移动端场景设计
Avatar - 当多个工具都需要底部抽屉交互时 → 从实现中抽取通用骨架
主题层面:
- 主题 store 已在输出 AIO Hub 项目 token,Varlet 变量作为派生兼容层
- 质感系统(壁纸、模糊、透明度)在移动端按需逐步移植
- 低端 Android 设备保留
backdrop-filter降级策略
判断标准
什么时候该动某个 Varlet 容器组件?
- 新功能开发时:如果新页面/功能用 Varlet 容器搭骨架,会导致后续定制成本高于自建 → 直接用 Vue 原生写
- 维护痛点时:某个 Varlet 容器的样式覆盖
:deep()已经累积到影响可维护性 → 提取替代组件 - 气质冲突时:某个 Varlet 容器的默认视觉在整体页面中明显格不入 → 替换
什么时候不急着动?
- 用着没明显问题、样式覆盖可控 → 留着
- 只在测试页面(如 ui-tester)使用 → 不管它
6. 新增代码规则
新增移动端页面时遵循:
- 优先写语义清楚的 Vue 结构,不用 Varlet 容器搭页面。
- 页面级组件放
views/,工具内部业务组件放tools/{toolId}/components/。 - 跨工具可复用的移动端骨架进
components/base/。 - 跨工具品牌/通用组件进
components/common/。 - Varlet 只在叶子节点使用;如果必须用作结构容器,代码注释或 PR 说明里写明这是临时兼容。
- 不新增裸
Snackbar/Dialog业务调用。 - 不新增以 MD3 / Varlet 变量为主语的主题设计。
7. 当前债务清单
| 债务 | 紧迫度 | 处理方向 |
|---|---|---|
Snackbar / Dialog 散落 | 高 | 先封装再替换 |
var-cell 承担设置/列表信息架构(40+ 处) | 中 | 碰到定制痛点时逐步替换,不急于一次性迁移 |
var-app-bar 承担页面顶部栏(~12 处) | 低 | 目前够用,品牌需求驱动时再动 |
var-popup 承担编辑器骨架(~11 处) | 低 | 目前够用,不急 |
var-paper 承担分组容器(~6 处) | 低 | CSS 几行就能替代,不单独排期 |
| 主题仍有 MD3/Varlet 主导痕迹 | 中 | 持续反转为 AIO token 主导 |
8. 决议记录
| 日期 | 决议项 | 结论 | 决议人 |
|---|---|---|---|
| 2026-06-09 | Varlet 定位 | 降级为类似桌面端 Element Plus 的底层组件库 | 用户 |
| 2026-06-09 | 移动端整体实现 | 以 Vue 原生组件、项目 CSS token 和自研业务骨架为主 | 用户 |
| 2026-06-09 | 主题方向 | AIO Hub token 主导,Varlet 变量只是兼容输出 | 用户 |
| 2026-06-09 | 产品定位 | AIO Hub 是统一框架下的可扩展能力枢纽,不是传统小工具合集 | 用户 |
| 2026-06-09 | 组件沉淀策略 | 需求驱动,不照搬桌面端清单;弹窗类当前够用不急着替换 | 用户 |
9. 修订历史
| 版本 | 日期 | 变更 |
|---|---|---|
| v1 | 2026-05-31 | 初稿,误把"用户高定制态"当作产品默认形象 |
| v2 | 2026-05-31 | 修正 DNA 为"高度可定制视觉系统 + 品牌一致性元素" |
| v2.1 | 2026-05-31 | 删除错误的底部 V 形品牌锚点 |
| v3 | 2026-05-31 | 提出组件抽象层路线,但把全量自研写得过早 |
| v3.1 | 2026-05-31 | 改为先组件适配性调查,再决定下沉清单 |
| v4 | 2026-06-09 | 根据实际体验直接决议:Varlet 降级为底层组件库,移动端回到 Vue 原生组件和 AIO 自有主题主导 |
| v4.1 | 2026-06-09 | 修正产品定位表述:强调 AIO Hub 不是传统小工具合集,而是在统一框架下承载复杂能力、降低使用门槛的工具枢纽 |
| v4.2 | 2026-06-09 | 修正 §3/§5 的照搬桌面端问题:组件清单改为需求驱动式沉淀,迁移路线改为痛点触发而非预建组件库 |