Skip to content

移动端设计语言与 Varlet 降级决议

状态: Accepted v4.2 作者: miaotouy / 咕咕 / Codex 日期: 2026-06-09 前提: 移动端尚未对外发布,仍处于内部构建阶段,无线上兼容性债务


版本演进

版本核心命题状态
v1把"玻璃质感"当作 AIO Hub 的 DNA错判
v2DNA 修正为"高度可定制视觉系统 + 品牌一致性元素",但仍在"换不换 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 一样提供底层组件能力;但不能继续决定移动端页面骨架、主题表现、容器语义和默认审美。

移动端的新定位:

text
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

桌面端的真实分层是:

text
页面骨架 / 业务容器 / 复杂交互  -> 自研 Vue 组件
通用能力组件                -> src/components/common/
按钮 / 输入 / 选择等原子件     -> Element Plus
命令式消息与弹窗              -> customMessage / BaseDialog 等项目封装

这套分层的价值不只是"组件自研"或"看起来统一",更重要的是让功能开发可以无痛并入统一框架:工具按 registry 接入,页面和服务能力按约定组织,主应用不为每个新工具反复改动路由和骨架。移动端应该继承的是这种可扩展产品框架,而不是把所有能力压平成松散入口列表。

移动端应对齐这套思想:

text
页面骨架 / 工具容器 / 移动交互  -> 自研 Vue 组件
移动端基础组件                -> mobile/src/components/base/
跨工具通用组件                -> mobile/src/components/common/
按钮 / 输入 / 选择等原子件     -> Varlet 可用但不主导
命令式消息与弹窗              -> customMessage / customDialog 项目封装

2. Varlet 新定位

2.1 可以保留的范围

Varlet 可以继续用于:

  • var-button
  • var-input
  • var-select
  • var-switch
  • var-slider
  • var-checkbox
  • var-radio
  • var-chip
  • `var-loading其他低风险、叶子节点级组件
  • Snackbar / Dialog 的底层实现,但必须经项目封装后调用

这些组件的角色与桌面端的 <el-button><el-input><el-select> 类似:省实现成本,但不定义产品骨架。

2.2 不应继续承担的范围

以下组件不应作为新增页面或重构后的主结构来源:

  • var-app-bar
  • var-popup
  • var-cell
  • var-card
  • var-paper
  • var-bottom-navigation
  • var-style-provider 对项目主题的主导权

已有代码可以渐进迁移,但新增代码不要继续扩大这些组件的结构性占比。

2.3 命令式 API

业务代码不应继续散落:

ts
import { Snackbar, Dialog } from "@varlet/ui";

目标是统一替换为:

ts
import { customMessage } from "@/utils/customMessage";
import { customDialog } from "@/utils/customDialog";

底层仍可调用 Varlet,但调用点必须收敛,API 与桌面端习惯对齐。


3. 目标分层

3.1 目录结构

text
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 已知的未来需求(参考,非硬性清单)

以下组件在移动端功能扩展过程中大概率会需要,但具体实现时机和形态应由实际场景决定:

组件触发条件备注
AvatarChat 功能完善、用户档案系统接入时按移动端场景重新设计,不照搬桌面端
BaseAppBarvar-app-bar 的样式限制成为多页面痛点时目前 var-app-bar 基本够用
BaseSheetvar-popup 无法满足自定义需求时目前 var-popup 用着还行
BaseListItemvar-cell 在设置页的气质/定制问题频繁出现时这是当前使用最密集的容器组件(40+ 处)

4. 主题规则

4.1 主从关系

主题主从关系必须明确:

text
AIO Hub token -> 移动端 Vue/CSS 组件 -> Varlet 兼容变量

不能倒过来:

text
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

  1. 建立 mobile/src/utils/customMessage.ts,包装 Varlet Snackbar
  2. 建立 mobile/src/utils/customDialog.ts,包装 Varlet Dialog
  3. 替换业务代码里散落的 Snackbar / Dialog 直接调用。
  4. 底层仍用 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 容器组件?

  1. 新功能开发时:如果新页面/功能用 Varlet 容器搭骨架,会导致后续定制成本高于自建 → 直接用 Vue 原生写
  2. 维护痛点时:某个 Varlet 容器的样式覆盖 :deep() 已经累积到影响可维护性 → 提取替代组件
  3. 气质冲突时:某个 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-09Varlet 定位降级为类似桌面端 Element Plus 的底层组件库用户
2026-06-09移动端整体实现以 Vue 原生组件、项目 CSS token 和自研业务骨架为主用户
2026-06-09主题方向AIO Hub token 主导,Varlet 变量只是兼容输出用户
2026-06-09产品定位AIO Hub 是统一框架下的可扩展能力枢纽,不是传统小工具合集用户
2026-06-09组件沉淀策略需求驱动,不照搬桌面端清单;弹窗类当前够用不急着替换用户

9. 修订历史

版本日期变更
v12026-05-31初稿,误把"用户高定制态"当作产品默认形象
v22026-05-31修正 DNA 为"高度可定制视觉系统 + 品牌一致性元素"
v2.12026-05-31删除错误的底部 V 形品牌锚点
v32026-05-31提出组件抽象层路线,但把全量自研写得过早
v3.12026-05-31改为先组件适配性调查,再决定下沉清单
v42026-06-09根据实际体验直接决议:Varlet 降级为底层组件库,移动端回到 Vue 原生组件和 AIO 自有主题主导
v4.12026-06-09修正产品定位表述:强调 AIO Hub 不是传统小工具合集,而是在统一框架下承载复杂能力、降低使用门槛的工具枢纽
v4.22026-06-09修正 §3/§5 的照搬桌面端问题:组件清单改为需求驱动式沉淀,迁移路线改为痛点触发而非预建组件库

Released under the Apache-2.0 License.