70 · 改造 Checklist
📌 本文目标:把 Vue 3 改造任务拆解为 7 个 Phase 的可执行清单。前端智能体按 Phase 逐项打勾,每完成一个 Phase 跑一次 §10 验收脚本。
Phase 1 · 项目初始化(0.5 d)
1.1 脚手架
- 用 Vite 创建 Vue 3 + TS 项目:
npm create vite@latest xistudio-shell -- --template vue-ts - 进入项目:
cd xistudio-shell && npm install - 安装核心依赖:
npm i pinia pinia-plugin-persistedstate vue-router@4 @vueuse/core - 安装类型依赖:
npm i -D @types/node
1.2 目录结构
- 创建
src/styles/src/stores/src/composables/src/types/src/components/shell/src/components/stage/src/components/dialogs/src/router/src/constants/ - 创建
public/stages/
1.3 资源同步
- 复制
docs/02-products/P1-xistudio/layout-demo/xistudio-codex.css→src/styles/xistudio-codex.css(字节级 1:1) - 复制
docs/02-products/P1-xistudio/layout-demo/xistudio-codex.css→public/stages/xistudio-codex.css(iframe 端用) - 复制 4 个 stage HTML 到
public/stages/stage-{xilink,xitune,xiforge,xitest}.html - 写
scripts/sync-stages-from-demo.sh用于后续同步
1.4 配置文件
-
vite.config.ts配置@别名指向src -
tsconfig.json启用严格模式"strict": true -
.eslintrc配置 Vue 3 + TS 规则 -
.prettierrc配置(与 demo 风格对齐)
1.5 主入口
-
src/main.ts挂载 Pinia + persistedstate + Router + 启动 license.fetch() -
src/App.vue仅<RouterView /> -
src/main.ts顶部import './styles/xistudio-codex.css'
1.6 Phase 1 验收
-
npm run dev启动成功 - 浏览器打开本机 http://localhost:5173 显示空白页(无报错)
- DevTools 中可见
xistudio-codex.css已加载
Phase 2 · Shell 组件树(1.5 d)
2.1 创建组件骨架
-
src/components/shell/XiStudioShell.vue(grid-template-areas 根布局) -
src/components/shell/MenuBar.vue(① 28px) -
src/components/shell/StageBar.vue(② 44px · 4 Pill + ToolBar) -
src/components/shell/SubTabs.vue(③ 32px) -
src/components/shell/ActivityBarLeft.vue -
src/components/shell/ActivityBarRight.vue -
src/components/shell/DrawerLeft.vue -
src/components/shell/DrawerRight.vue -
src/components/shell/DrawerHeader.vue(grid 两行 + ellipsis) -
src/components/shell/BottomPanel.vue(5 tab 互斥) -
src/components/shell/StatusBar.vue(三分区) -
src/components/stage/StageFrame.vue(iframe 容器) -
src/components/dialogs/TuningDialog.vue(<Teleport to="body">)
2.2 类名严格匹配 codex.css
- 所有组件根 div 用法典类名(
.ide.menubar.stagebar.subtabs.actL.actR.body.bottom.status.drawer.dock-icon) - grep 验证:
grep -rn "activity-icon" src/必须为空 - grep 验证:
grep -rn "display.*block" src/components/不出现在 view-pane / bottom-pane(用.active类切换)
2.3 静态结构 + 占位内容
- 暂用 mock 数据填充各组件(4 Pill / 9 菜单 / 5 Bottom tab 等都用静态数据)
- 不接 store,先确保视觉骨架对齐 demo
2.4 Phase 2 验收
- 浏览器打开页面,与 demo 视觉骨架基本一致(grid 布局正确)
- DevTools Inspector 验证:
.ide.topbar.body等 grid-area 正确 - 类名 grep 通过
Phase 3 · Pinia stores(1 d)
3.1 创建 4 核心 store + 2 会话级
-
src/stores/layout.ts(useLayoutStore) -
src/stores/stage.ts(useStageStore) -
src/stores/license.ts(useLicenseStore) -
src/stores/theme.ts(useThemeStore) -
src/stores/stage-bar.ts(useStageBarStore · 会话级) -
src/stores/tuning-dialog.ts(useTuningDialogStore · 会话级)
3.2 持久化字段对齐 demo
-
useLayoutStore持久化 key =xistudio-layout-v1,paths 包含lockeddrawerLeftdrawerRightbottom -
useStageStore持久化 key =xistudio-stage-v1 -
useThemeStore持久化 key =xistudio-theme-v1
3.3 组件接入 store
- XiStudioShell 接 layout/stage/theme
- StageBar 接 stage/license/stageBar
- DrawerLeft/Right 接 layout
- BottomPanel 接 layout
- StatusBar 接 layout/license/stage
3.4 license fetch 与默认 Stage
- main.ts 中调
useLicenseStore().fetch() - License mock 返回 4 Stage 全开(开发期)
- 启动后
useStageStore().current = useLicenseStore().defaultStage
3.5 Phase 3 验收
- 在 Vue Devtools Pinia tab 中可见所有 6 个 store
- localStorage 中可见
xistudio-layout-v1xistudio-stage-v1xistudio-theme-v1 - 关键验证:手动在 demo 中操作产生 localStorage
xistudio-layout-v1,刷新到 Vue 项目能正确恢复布局
Phase 4 · postMessage Bridge + Stage iframe(1 d)
4.1 类型定义
-
src/types/stage-bridge.ts完整 11 类协议 TS 类型(参见 40-postmessage-protocol.md §2)
4.2 composable
-
src/composables/useStageBridge.ts实现 on/send + 来源校验
4.3 StageFrame 接入
- StageFrame.vue 注册 9 类 Stage→Shell handler
- iframe
:src绑定STAGE_SRC[stage.current] - watch
stage.current切换时清空所有 Stage 注入槽位
4.4 Stage 端验证
- 启动 Vue 项目,4 个 Pill 切换 → iframe 正常加载对应 stage HTML
- Stage 发
stage-ready→ useStageStore.state 变为'ready' - Stage 发
toolbar-inject→ StageBar 右半区显示工具按钮 - Stage 发
inspector-inject→ DrawerRight Inspector 显示内容 - Stage 发
tuning-dialog→ TuningDialog 浮窗弹出
4.5 Phase 4 验收
- 4 Pill 切换无残留(toolbar/inspector/properties/status/hint 槽位都被清空)
- 跨 Stage 浮窗(Tuning Dialog)切 Stage 后继续显示
- DevTools Console 无
[useStageBridge] reject foreign message警告
Phase 5 · 窗口管理(1.5 d)
5.1 Drawer Dock 4 位置切换
-
src/composables/useDrawerDock.ts实现 setDockPos / setRatio - DrawerHeader 提供 dock 位置切换按钮(4 位置 popover)
- 切换 dockPos 时 grid-area 重排
5.2 Drawer ½/⅓/¼ 比例
- DrawerHeader 提供比例切换(3 选项)
- 切换 ratio 时 grid-template-columns / rows 重新计算
-
useLayoutStore.gridColumns/gridRowsgetter 正确返回 fr 值
5.3 Resize 拖拽
-
src/composables/useWindowResize.ts实现 startResize / onMouseMove / onMouseUp -
<Resizer>组件挂载在 Drawer 与 BottomPanel 边缘 - 拖拽时实时更新 ratio(quantize 到 ½ / ⅓ / ¼ 三档)
5.4 Lock 模式切换
- MenuBar 添加 Lock 切换按钮
-
useLayoutStore.toggleLock()切换.ide.locked类 - locked 与 float 模式视觉差异符合 demo
5.5 dock-icon 单击切换(v3.4 bug 修复)
- ActivityBarLeft/Right 实现单击 toggle 逻辑(参见 20-shell-component-tree.md §6.3)
5.6 Phase 5 验收
- Drawer Dock 4 位置切换正常(left/right/top/bottom)
- Drawer ½/⅓/¼ 比例切换正常
- Resize 拖拽流畅,松开时 quantize 到三档
- Lock 切换视觉与 demo 一致
- dock-icon 单击直接切换(不需要点两次)
Phase 6 · 跨 Stage 浮窗 + 主题(0.5 d)
6.1 TuningDialog
- TuningDialog.vue 用
<Teleport to="body">渲染 - 拖拽功能(onDragStart / onMouseMove)
- 关闭 / 最小化按钮
- 最小化进 BottomPanel B6 Tuning 托盘
6.2 主题切换
- MenuBar ThemePicker 6 主题 popover
- 切换主题时
[data-theme]切换 - 通过 postMessage
theme消息(需要新增 ADR)通知 iframe 同步切换
6.3 Phase 6 验收
- TuningDialog 跨 Stage 切换持续存在
- 6 主题切换 Vue 端 + iframe 端同步生效
- 截图 diff 与 demo < 1%
Phase 7 · 验收 + E2E(1 d)
7.1 单元测试(Vitest)
-
tests/unit/stage-bridge.spec.ts -
tests/unit/layout-store.spec.ts -
tests/unit/license-store.spec.ts -
tests/unit/drawer-dock.spec.ts
7.2 E2E 测试(Playwright)
11 个核心场景(对应 11 commit):
- T1 · XiLink Stage iframe 加载 + Tuning Dialog 拉起
- T2 · VSCode 锁定模式切换(locked / float)
- T3 · Drawer Dock 4 位置切换
- T4 · Drawer Header Title ellipsis(窄宽度)
- T5 · Bottom Tab 互斥(5 tab 切换)+ Stage Hint 槽
- T6 · 通用骨架 PEQ + Drawer 项目树/Inspector
- T7 · dock-icon 单击切换 + Inspector/Properties 注入
- T8 · XiTune Stage 加载(3 列)
- T9 · XiForge Stage 加载(2 列 + 5 sub-tabs)
- T10 · XiTest Stage 加载(4 KPI + SVG 趋势)
- T11 · 4 Pill 切换无残留
7.3 视觉回归测试
- 与 demo 同分辨率截图(1920×1080)
- 像素 diff < 1%(用 pixelmatch 或 puppeteer-screenshot-tester)
7.4 字节兼容验证
-
diff src/styles/xistudio-codex.css ../layout-demo/xistudio-codex.css输出为空
7.5 TS 严格模式
-
npx tsc --noEmit通过(零错误) -
npx eslint src/通过
7.6 性能基线
- 首屏 LCP < 2s(lighthouse)
- localStorage 存储大小 < 10KB
7.7 Phase 7 验收(终极交付门槛)
风险点与预案
| 风险 | 预案 |
|---|---|
| codex.css 与 Vue 类名冲突 | grep 验证 + 字节兼容 diff(每 Phase 验收) |
| postMessage 协议漂移 | TS 严格类型 + Vitest 测试 + ADR 强制流程 |
| localStorage 持久化字段不兼容 demo | 在 Phase 3 验收时手动跑「demo 操作 → Vue 项目恢复」测试 |
| iframe 与 Vue 主题不同步 | 强制走 postMessage theme 协议(ADR 登记) |
| Stage iframe 加载缓慢 | StageFrame 加 loading 蒙层 + 10s 超时 |
| 复杂的 dock 位置切换 grid 计算 bug | useLayoutStore.gridColumns / gridRows 写单元测试覆盖所有组合 |
| 资源同步遗漏(demo 改了 Vue 没改) | CI 跑 scripts/sync-stages-from-demo.sh + diff 检查 |
回滚预案
如某 Phase 出现严重问题:
- Phase 1-2 回滚:删除 src 目录重新走 1-2
- Phase 3 回滚:清空
localStorage(避免脏数据),重写 store - Phase 4 回滚:postMessage 协议变更必须 ADR 登记后再修
- Phase 5-6 回滚:单独 git revert 该 Phase 的 commit
- Phase 7 验收失败:回到对应 Phase 重做相关项目,不要降低验收标准
进度看板(本文档活动版)
| Phase | 工作量 | 状态 | 完成日期 | 备注 |
|---|---|---|---|---|
| 1 · 项目初始化 | 0.5 d | ☐ | — | — |
| 2 · Shell 组件树 | 1.5 d | ☐ | — | — |
| 3 · Pinia stores | 1 d | ☐ | — | — |
| 4 · postMessage Bridge | 1 d | ☐ | — | — |
| 5 · 窗口管理 | 1.5 d | ☐ | — | — |
| 6 · 浮窗 + 主题 | 0.5 d | ☐ | — | — |
| 7 · 验收 + E2E | 1 d | ☐ | — | — |
| 总计 | 7 d | 0% | — | — |
📝 智能体每完成一个 Phase 把状态从 ☐ 改为 ✅,并填日期。
10. 验收脚本(每 Phase 收尾跑一次)
#!/bin/bash
# scripts/phase-verify.sh
set -e
echo "1. TS 编译"
npx tsc --noEmit
echo "2. ESLint"
npx eslint src/ --ext .vue,.ts
echo "3. codex.css 字节兼容"
diff src/styles/xistudio-codex.css ../docs/02-products/P1-xistudio/layout-demo/xistudio-codex.css
echo "4. 类名 grep(防止反模式)"
if grep -rn "activity-icon" src/; then
echo "❌ 发现 .activity-icon 类(应为 .dock-icon)"
exit 1
fi
echo "5. 单元测试"
npx vitest run
echo "6. 构建测试"
npx vite build
echo "✅ 所有验收通过"
v1.0 · 2026-05-17 · D4 前端改造手册 · 改造 Checklist · 配套 v1.2.2-impl §12