Vue2 转 Vue3 AI 批处理操作手册

这篇是 Vue2→Vue3 迁移系列的"操作手册"——配合前两篇(方案推演实操上实操下)使用效果最佳。 前两篇讲"为什么"和"怎么做",这篇讲"打开电脑后具体敲什么命令"。

这份手册记录的是我在实际项目中沉淀下来的 AI 批处理工作流。工具本身不复杂,核心价值在 Prompt 和配置策略上。

开始之前,先知道几个风险

  1. 样式不处理——该方案完全不涉及 CSS。页面长什么样从代码里读不出来,AI 没有可靠的 UI 转换方案。样式修正需要额外评估。
  2. 不修 Bug——主要功能是 Vue 版本迁移,不会顺手修原有问题(当然你可以自己写 prompt 让它试)。
  3. 大文件会截断——超过 ~800 行代码的文件,大模型输出可能被截断。
  4. 输出 token 上限——当前大模型普遍只支持到 6000-8000 tokens 的输出长度。

环境准备

Python 依赖

pip3 install dashscope GitPython openai Requests

Node 版本

Node 18+。如果原项目用的是 Node 14/16,迁移过程中需要升级。

核心思路:一个任务一个配置

这个工作流的设计哲学是任务粒度可控。每个配置文件包含:

  • 输入目录(源码在哪)
  • 输出目录(结果写到哪)
  • 文件匹配规则(处理哪些文件)
  • Prompt 文件(怎么处理)
  • 模型配置(用什么模型、什么参数)

任务规划

按经验,一般需要 3-4 个任务:

任务说明执行顺序
mixins → hooks将 mixin 转为组合式 hooks(仅组合式路线需要)1️⃣ 最先
JS 文件处理处理 router、vuex、入口文件等2️⃣
Vue 文件处理(选项式)保持选项式,只做版本兼容3️⃣
Vue 文件处理(组合式)转为 <script setup> 风格3️⃣(与选项式二选一)

如果在 Vue3 项目中想同时保留组合式和选项式风格,建议把转换前的 mixin 也保留在项目里——选项式的文件用不了 hooks,还是要用原来的 mixin。

Prompt 模板

在项目根目录新建一个 fe-pal-rc 目录(或任何你喜欢的名字),存放所有 Prompt 和配置文件。

mixin → hooks Prompt

# 任务
对上面的代码进行如下处理
 
## 重构 mixin 为 hooks
- 将 Vue2 的 mixin 转换为 Vue3 组合式 API(hooks)
- 所有 hooks 通过单独导出语句导出,不使用 export default
- hooks 增加 mixinProps 入参:
  - key 是原 methods 中所有方法名,值是方法
  - hooks 内部优先执行 mixinProps 传入的方法
 
## this 处理
- this.$store → vuex4 写法
- this.$emit → defineEmits
- this.$nextTick → nextTick
- this.$router → useRouter()
- this.$route → useRoute()
- this.$refs.xxx → vueInstance.refs.xxx
- 其他 this.xxx → vueInstance.setupState.xxx
 
## element-ui → element-plus
- ElMessage 使用 import { ElMessage } from 'element-plus'
 
## 约束
- 多级引用使用 ?.
- 即使不需要修改也返回原代码
- 只返回代码文本,不返回 markdown 格式

JS 文件 Prompt

在 mixin prompt 基础上增加:

  • 动态引入requireimport.meta.glob(Vite 方式)
  • Vue.prototypevueInstance.proxy
  • Router 冲突:避免变量名与 createRouter 冲突
  • Vuex module:不对 module store 用 createStore 重构
  • 国际化VueI18ncreateI18n
  • 知识库:如果前面已经把 mixin 转成了 hooks,把 hooks 代码附在 prompt 末尾

JS 任务需要排除掉 mixin 文件(已经在第一步处理过了)。

Vue 文件 Prompt(选项式)

选项式的 Prompt 非常精简:

# 任务
## 重构要求
- 重构为非 TypeScript 的 Vue3 选项式代码
- 不允许使用组合式风格
 
## element-plus
- ElMessage 使用 import { ElMessage } from 'element-plus'
 
## 约束
- 多级引用使用 ?.
- 即使不需要修改也返回原代码
- 只返回代码文本

Vue 文件 Prompt(组合式)

组合式需要更多指令:

  • 使用 <script setup> 风格
  • data 属性 → ref()
  • template 中的 ref 属性 → Vue3 的 ref() 方式
  • {{ value | function(args) }}{{ function(value, args) }}
  • 末尾附上知识库(mixin → hooks 的对应关系)

任务配置

每个任务对应一个 JSON 配置文件:

{
    "sourcePath": "./src-vue2",
    "destinationPath": "./src",
    "include": ["**/*.vue"],
    "exclude": ["**/node_modules/**"],
    "promptFilePath": "./fe-pal-rc/vue-options.p.md",
    "modelConfig": {
        "api_key": "你的 API Key",
        "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
        "model": "qwen-long",
        "stream": true,
        "temperature": 0.1
    }
}

关键参数说明:

  • sourcePath / destinationPath:输入输出分离,方便重复执行
  • temperature: 0.1:处理代码时务必调低,减少"创造性发挥"
  • stream: true:解决大文件超时问题
  • model:推荐 qwen-longqwen-max-latest

执行

# 按顺序执行
fe-pal ./fe-pal-rc/mixins2hooks.json    # 1. mixin → hooks
fe-pal ./fe-pal-rc/js.json              # 2. JS 文件
fe-pal ./fe-pal-rc/vue-options.json     # 3. Vue 文件

实操贴士

目录策略

project/
├── src/            ← 输出目录(AI 转换结果)
├── src-vue2/       ← 备份目录(原始 Vue2 源码,不动)
├── src-temp/       ← 临时目录(单个文件的定点处理)
├── src-temp-dist/  ← 临时输出
└── fe-pal-rc/      ← Prompt + 配置文件

这样安排的好处:

  1. 原始文件保持不变,方便重复处理
  2. 清楚区分哪些是处理前、哪些是处理后
  3. src-temp 用于单个文件的定点调试,不影响全局任务

从最简单的页面开始

不要上来就跑全量。建议:

  1. 选一个简单页面,先把 router 和状态管理跑通
  2. 如果是迁移到已有的 Vue3 项目,router 可能不需要处理
  3. 页面跑起来后按报错逐个修复
  4. 调试几次就会比较熟练

接口模拟

想让页面看起来正常,需要能调用业务接口。推荐用 whistle 做接口代理——把 API 请求转发到可用的开发/测试环境。

处理截断

文件超过 ~800 行就要警惕截断:

  • CSS 截断:直接把原始 CSS 复制过来补上
  • 代码截断:拆分文件,或者在 prompt 里限定"只返回 template"/"只返回 script"
  • 执行失败:找到 processed_files.txt,删掉出错文件的路径,重新执行

踩坑经验池

Vue 相关

问题解决方案
Vite 引用 .vue 文件需要扩展名配置 resolve.extensions
全局变量不能挂载到 Vue 实例getCurrentInstance() 间接引用
变量重复声明(this.xxxxxx 同名)手动处理,目前无自动方案
hooks 中方法声明顺序导致引用报错手动调整声明位置
watch(props.xxx) 不响应改为 watch(() => props.xxx)
// ❌ 转换后可能出现的问题
const xxx = useXXX(func)
const func = function() { /* ... */ }
// func 还没声明就被使用了
 
// ✅ 手动调整顺序
const func = function() { /* ... */ }
const xxx = useXXX(func)

element-plus 相关

问题解决方案
icon 名称对不上建立映射表统一处理
某些组件用 model-value 而非 v-model遇到时手动处理,或穷举写入 prompt

关于测试

这个方案对测试流程没有直接影响——该写的测试还是要写。

但如果项目已有测试用例,可以尝试把用例放到 prompt 中让 AI 做粗检验,对测试环节能起到一些辅助作用。


系列导航:

  1. 方案推演:Vue2→Vue3 路线选择 — 要不要迁?选哪条路?
  2. 实操(上):组合式路线 — Prompt 工程与完整流程
  3. 实操(下):选项式路线与现实收尾 — gogocode + AI 补刀
  4. 操作手册 — 你正在读的这篇

Comments