docs/archives/124-advanced-mode-toggle-migration/experience.md
成功实践: 使用MCP Spec Workflow进行结构化迁移
价值体现:
传统方式: 直接修改 → 发现问题 → 回滚重试 → 反复调试
系统化方式: 分析 → 规划 → 实施 → 验证 → 一次成功
推广建议: 所有UI框架迁移都应采用类似的系统化方法
核心理念: 外部接口保持不变,内部实现完全重构
具体实践:
// Props接口完全保持不变
interface Props {
enabled?: boolean
disabled?: boolean
loading?: boolean
}
// Events接口完全保持不变
const emit = defineEmits<{
'update:enabled': [boolean]
'change': [boolean]
}>()
经验价值: 零破坏性迁移,无需修改任何调用方代码,降低迁移风险
从手动CSS到工具类:
/* 迁移前:手动媒体查询 */
@media (max-width: 768px) {
.text { display: none; }
}
/* 迁移后:语义化工具类 */
<span class="text-sm max-md:hidden">...</span>
关键优势:
max-md:hidden 一目了然策略: 在迁移过程中适当添加新功能,提升用户体验
// 新增loading状态管理
const loading = ref(false)
const handleToggle = async () => {
loading.value = true
try {
// 原有逻辑
} finally {
loading.value = false // 防重复点击
}
}
效果: 不仅完成迁移,还改善了用户交互体验
问题发现: 在迁移测试中发现 NFlex 组件无法正常导入
根本原因分析:
// packages/ui/src/index.ts 缺少关键导出
// 导致其他组件无法正确引用NFlex
import { NFlex } from '@prompt-optimizer/ui' // ❌ 失败
解决方案:
// 补充导出
export { NFlex } from 'naive-ui'
深层教训:
预防措施:
问题场景: Toast组件出现 inject() 上下文错误,影响用户反馈显示
技术根因:
// 问题:在错误的Vue上下文中初始化MessageAPI
const message = inject('n-message') // ❌ 上下文不存在
根本解决:
// 采用全局单例模式,确保正确初始化
let globalMessageApi: MessageApi | null = null
export const useToast = () => {
if (!globalMessageApi) {
throw new Error('Toast system not initialized')
}
return globalMessageApi
}
架构改进:
经验价值:
挑战: 从自定义主题变量转换到Naive UI主题系统
原有实现的问题:
/* 依赖大量CSS变量,维护复杂 */
.button {
background-color: var(--color-bg-hover);
color: var(--color-text-primary);
border: 1px solid var(--color-border);
}
现代化解决方案:
<!-- 利用Naive UI内置主题能力 -->
<NButton :type="buttonType" :ghost="!enabled">
核心优势:
踩坑过程:
// 直觉的错误映射
:disabled="props.disabled" // ❌ 忽略了loading状态
// 正确的复合映射
:disabled="props.disabled || loading" // ✅ 考虑所有状态
避坑指南: 迁移时需要考虑原有逻辑的所有状态组合,不能简单1:1映射
踩坑过程:
<!-- 错误的Tailwind类名组合 -->
<div class="absolute -top-1 -right-1 w-3 h-3"> <!-- ❌ 尺寸偏大 -->
<!-- 精确的像素级控制 -->
<div class="absolute -top-0.5 -right-0.5 w-2 h-2"> <!-- ✅ 视觉完美 -->
避坑指南: Tailwind的数值系统需要精确理解,0.5 = 2px,1 = 4px
踩坑记录:
<!-- 直觉的错误写法 -->
<NButton>
<svg>...</svg> <!-- ❌ 图标位置不对 -->
</NButton>
<!-- 正确的slot写法 -->
<NButton>
<template #icon><svg>...</svg></template> <!-- ✅ 专门的图标slot -->
</NButton>
经验总结: Naive UI的slot设计更加精细化,需要按照组件API正确使用
总结: 这次迁移不仅是技术升级,更是一次系统化工程实践的成功案例。通过结构化方法、向后兼容设计、问题快速解决,最终实现了技术目标和业务价值的双重成功。这些经验对未来的类似项目具有重要的参考价值。