ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vue2到Vue3迁移实战:用Trae AI IDE与Skills高效改造form-generator

Vue2到Vue3迁移实战:用Trae AI IDE与Skills高效改造form-generator 1. 项目起点form-generator升级背后的真实动机先交代一下背景。form-generator这个项目熟悉低代码或者表单开发的朋友应该不陌生它是一款基于Vue2的开源表单设计器核心能力是拖拽式生成表单、维护JSON配置、一键生成代码。很多团队拿它做后台管理系统的表单引擎也有人在里面二次开发接自己的业务组件。我这次要做的是把这套老项目整体升级到Vue3而且整个升级过程不是纯手工改造是全程在Trae这款AI IDE里配合Skills机制来完成的。先说为什么要升级。一是我这边的技术栈已经整体迁移到Vue3 Vite TypeScript老的form-generator还停在Vue2 Webpack维护成本越来越高。二是团队新人在Vue3环境下改老代码心智负担很大与其继续打补丁不如一次性把底子换掉。三是form-generator本身的设计其实非常依赖Vue2的某些特性比如$children遍历、$listeners透传、slot作用域传参、mixins复用逻辑这些在Vue3里要么被移除要么行为完全不同升级难度并不低不是改改依赖版本号就能跑起来的。这次升级我给自己定了一条规矩所有代码改动尽量通过Trae的对话和Skills流程来完成人工只负责审查、纠错和决策。也就是说我要把“升级老项目”这个活变成一套“AI协作流程”让模型替我读代码、改代码、排查报错我做把关人。整体做下来周期大概一周对比我之前纯手改一个类似的Vue2项目效率提升还是相当明显的。这篇文章就把整个过程拆开讲一遍包括改了什么、为什么这么改、Trae和Skills在里面到底起了多大作用以及那些文档里不会写明白的坑。适合来看这篇内容的人我猜大概是三类一类是自己手里有Vue2老项目要升Vue3想找个参考路线一类是想把AI IDE真正用进日常项目里但不满足于让它写点零散函数的人还有一类是玩过Trae但还没搞明白Skills怎么落地、怎么和真实项目结合的人。我会尽量把操作细节写得具体你照着走能少走不少弯路。2. 升级前的准备拆解老代码和规划迁移路径2.1 先盘点form-generator到底依赖了哪些Vue2特性在让Trae动手之前我先自己把仓库完整翻了一遍搞清楚这个项目的技术债集中在哪里。form-generator的代码结构大体分三块表单设计器主体、渲染器、组件库。设计器主体里最核心的是拖拽面板和JSON Schema的编辑逻辑渲染器负责把保存的JSON配置实时渲染成表单页面组件库则是一系列内置表单项比如输入框、下拉选择、日期选择、上传、子表单等。依赖的Vue2特性我列了个清单$children设计器里多处用来直接拿子组件实例比如拖拽后刷新组件列表。$listeners和$attrs组件库里的包装组件大量使用把事件和属性透传给原生组件。.sync修饰符弹窗显隐、表单值同步都有用到Vue3里合并到了v-model。全局事件总线组件之间通信用的是Vue.prototype.$bus new Vue()这种经典写法。mixins公共逻辑抽成了好几个mixins比如表单校验逻辑、下拉数据加载逻辑。slot-scope设计器渲染组件配置项时用了大量作用域插槽。过滤器filter一些展示格式化用了全局过滤器。Vue.extend和动态注册组件动态渲染表单组件时依赖了这类API。我不建议一上来就新建一个Vue3项目然后把代码拷进去那样报错会铺天盖地根本无从下手。比较合理的做法是先逐项确认项目里用了哪些API再对照Vue3的断崖式变更清单把它们分成三类可直接替换的、需要改写的、需要重新设计的。2.2 迁移方案选型为什么选渐进式迁移而不是推倒重来方案上我考虑过两条路。第一条是推倒重来用Vue3 TypeScript完整重写一遍form-generator保留核心交互和JSON Schema规范代码全部新写。第二条是渐进式迁移也就是先让老项目在Vue2.7上跑通把mixins、$children、$listeners等过时写法清理干净再整体切到Vue3。选渐进式是因为form-generator的业务逻辑很重尤其是拖拽排序、JSON Schema联动、组件配置面板这三个模块有大量边界逻辑和兼容处理推倒重来意味着这些暗坑要重新踩一遍而且无法用Git对比保证功能完全一致。渐进式迁移可以分模块逐步推进每个模块迁移完都能用现有测试数据去验证回归成本小得多。Trae在这里面扮演的角色很有意思它不是简单帮我改代码而是可以理解整条迁移路线。我在项目根目录建了一份迁移说明文档把上面说的依赖清单、迁移顺序、每个阶段的验收标准全部写了进去。Trae的Skills机制可以关联这份文档让AI在每次改代码前先理解全局约束而不是孤立地处理单个文件。这一点后面单独讲先继续说我怎么用Trae做代码诊断。2.3 用Trae先跑一遍全仓库扫描拿到“问题地图”我在Trae里建了一个会话任务很简单扫描整个form-generator仓库统计所有Vue2弃用API的使用位置和数量。得益于Trae能读取整个项目目录的上下文它不像传统搜索那样只做关键词匹配而是会结合代码语义去判断比如$children出现在什么场景下、被用来做什么、能不能安全替换。第一轮扫描结果出来比我自己预估的还要多。除了常见的$children、$listeners、.sync之外还有一堆隐蔽问题比如某些组件依赖了Vue.prototype.$set做响应式新增属性这在Vue3里完全不需要了但写法和思维惯性还在再比如全局过滤器在模板里的调用升级后必须改成函数调用或者computed。这轮扫描帮我把迁移范围精确到了文件级。我让Trae输出了一份Markdown格式的“问题地图”每个文件对应列出问题类型、影响范围、建议改法、优先级。这份文档后来成了整个升级过程的施工图也让后面所有Skills的针对性更强。我强烈建议你迁移前先做这一步不管用Trae还是手动检索先把债理清楚再动手效率差距非常大。3. 核心细节拆解Vue2到Vue3的关键升级点3.1 响应式体系的迁移$set、$delete和Vue.observable的替代form-generator里有一段很典型的老代码往对象上动态添加字段时用的this.$set(this.someObject, key, value)。这段逻辑在Vue2里是必须的因为Vue2的响应式是基于Object.defineProperty新增属性不会被拦截必须用$set手动触发更新。Vue3换成了Proxy对象本身是响应式的新增删除属性天然就能被捕获所以这些$set理论上可以直接去掉直接赋值就行。但实操里有个容易踩的坑有些逻辑是在组件内部往一个已经被赋值过的数组里塞对象对象内部的字段是后面才动态加的。升级的时候要确认这个对象是处在reactive还是ref容器里。如果你是reactive则直接加字段没问题但如果你习惯性把对象塞进了ref里再赋值那就要格外小心ref包裹的数据你要通过.value访问整个引用被替换时是响应式的但内部已有对象如果没有用reactive转一层依然会有失去响应式的风险。Trae在迁移这块最大的价值在于它能自动识别出那些“其实可以简化”的老代码。比如某个watch里还在配合$set做深拷贝、再赋值的老套路模型会告诉我这在Vue3里可以直接用结构替换加赋值代码量少一半。你要做的就是逐处审查这个建议是否符合业务逻辑而不是依赖模型一键替换。响应式这个问题属于“看起来很简单实际上水很深”的类型建议升级时专门留出时间一段一段审查每个对象和数组的使用场景。3.2 组件通信重构事件总线、$listeners和$attrs的处理form-generator设计器里组件之间的通信用了事件总线大概是this.$bus.$emit(some-event, payload)这种。Vue3移除了实例上的$on、$off、$once方法官方推荐的替代方案是推荐改用mitt这个微型事件总线库或者干脆改用provide/inject和props。实际迁移时我选了mitt因为form-generator里的总线事件至少有二十多种全部改成provide/inject工程量大而且事件总线的松耦合特性在这个场景里其实是合理的。用mitt改造成本极低把原来main.js里的Vue.prototype.$bus new Vue()改成import mitt from mitt加一个全局单例再把所有调用处的API换掉即可。注意emit和on的参数顺序、解绑方式几乎和原版一致所以这块的迁移基本是机械工作很适合丢给Trae处理。然后是$listeners。Vue2里父组件给子组件绑定的事件监听器可以通过$listeners拿到再透传给孙组件Vue3里$listeners被移除了事件监听器会和其他属性一起被并入$attrs并且框架层会自动把onXxx开头的attrs当作事件传给子组件根节点。所以迁移form-generator里的包装组件时最省事的方式是在组件上声明inheritAttrs: false然后统一用v-bind$attrs往下传丢弃原来手写的v-on$listeners。这块我在Trae里明确配置了一条规则“遇到$listeners全部改写成v-bind$attrs遇到.sync修饰符改写成对应update:propName事件”。Trae执行得很快但审查时我发现一个边界情况有的组件主动消费了$attrs里的部分class又往下传递命名有可能会重。遇到这种就手动调整一下把消费掉的属性显式声明为prop避免透传时被覆盖。3.3 组件声明与注册方式Vue.extend、动态组件的替代form-generator的动态表单渲染器核心逻辑是用Vue.extend把一个组件定义转成构造器再配合一个渲染函数动态实例化。这种写法在Vue3里完全行不通了因为Vue3组件定义是普通的JavaScript对象不再有“类”和构造器的概念。迁移这部分时我把原来的Vue.extend创建方式改成了用一个组件注册表加resolveComponent的方式提前把所有内置组件在应用实例上注册或者用defineAsyncComponent做按需加载然后在渲染器里通过组件的字符串名称动态解析。这样既保留了form-generator“通过JSON里的componentName映射到真实组件”的机制又完全走Vue3官方推荐的组件解析链路。这里有一个值得注意的细节Vue3的渲染函数虽然可以直接通过h(resolveComponent(SomeComponent))来动态渲染但如果你在script setup里使用模板内部的组件解析范围会限定在当前文件动态字符串组件无法被自动解析到。必须用resolveComponent显式获取或者把组件列表全局注册。我在form-generator升级时是做了一个统一入口把所有表单组件、布局组件、自定义组件集中到一个registerComponents.ts文件里全局注册渲染器只依赖这个全局注册表这样才保证了动态渲染的可靠性。3.4 mixins到composables的演进逻辑复用方式重写form-generator里有一批mixins比如表单校验逻辑、级联加载逻辑、远程选项数据逻辑。Vue3虽然还保留mixins但官方推荐用Composition API组合逻辑。迁移时我做了这样一个判断短期能跑的mixins继续留着也能运行但长期维护和团队认知统一最好还是改写成composables。我在Trae里给了一个比较具体的重构方向把原来mixins里的data、computed、methods拆成对应的ref、computed和普通函数统一放进useXxx.ts文件返回一个可解构的对象。比如原来一个remote-options-mixin负责从远端加载下拉选项、处理加载态和错误态重构成useRemoteOptions之后输入参数变成接口地址和请求参数返回值变成options、loading、error、loadOptions方法。这个改写过程其实非常适合AI来完成因为逻辑是平移不涉及重新设计。Trae读取了原始mixin后生成的composable基本可以直接用我只做了少量修正比如变量命名风格统一、类型定义补全。但我要提醒一点composables和mixins在数据共享上有个本质区别mixin里你可以直接通过this.xxx访问组件其他数据而composable的“共享”是通过入参传进去的设计时要显式定义好入参和返回值否则很容易写出隐式依赖前期省事后期维护爆炸。3.5 路由和全局API的调整Vue.prototype、全局过滤器的清理form-generator项目里除了核心设计器还有展示端和示例页面这块用到了路由。Vue3的路由从vue-router3升到vue-router4API变化不算大主要是new Router()变成了createRouter()模式设置、路由表写法基本兼容。我在升级时把路由配置表单独抽出来做成了routes.ts方便Trae和团队审查。更琐碎的是全局API的清理。form-generator原来的main.js里有大量Vue.prototype.xxx xxx的挂载比如全局的请求实例、工具函数、事件总线、常量配置。Vue3里对应的做法是用app.config.globalProperties.xxx xxx。但这里我走了另一条路除了少数必须挂在实例上的比如$http、$message其他工具函数一律改成ES Module按需导入。这是因为globalProperties上的东西在TypeScript里类型扩展很麻烦为了体验更顺手尽量少挂全局。还有全局过滤器。form-generator里做了几个展示用的过滤器比如时间格式化、金额千分位。Vue3移除filter选项后我在升级时统一把它们改成了工具函数模板里的写法从{{ value | formatTime }}改成了{{ formatTime(value) }}相应地在组件里import { formatTime } from /utils/format。如果你项目里有大量全局过滤器可以考虑通过app.config.globalProperties挂载成方法或者用computed在组件内预处理但无论哪种模板语法都要改这点没有捷径。3.6 插槽和作用域插槽slot-scope到v-slot的收尾form-generator的组件配置面板里大量使用了作用域插槽来渲染自定义配置项老写法基本是template slotxxx slot-scope{ row }。Vue3统一改成template v-slot:xxx{ row }缩写是#xxx{ row }。这块的迁移虽然机械但涉及文件多、嵌套深容易出错。我的建议是分两步先让Trae做全局替换把slotxxx和slot-scope语法统一转成v-slot再人工审查那些插槽名是动态拼接的场景。form-generator里就有这种写法插槽名是根据组件类型动态生成的比如slotconfig-${componentType}。v-slot不支持动态插槽名直接用字符串拼接必须用中括号语法#[config-${componentType}]。这些细节如果依赖全局替换很容易被漏掉审查的时候要重点翻一翻。4. 结合Trae和Skills的实操过程把AI协作真正落地4.1 Trae里的Skills到底是什么怎么配置才不白配Trae的Skills简单理解就是给AI定义“角色、知识、工作流”的一套机制。它类似Claude的Skills概念通过在项目目录里放.skills或skills文件夹里面用Markdown格式的SKILL.md描述一个技能的定义、规则、步骤AI会在对话时自动感知并加载这些技能。对于form-generator升级这种特定项目Skills可以把“这个项目的历史背景、技术约束、迁移规范”固化下来每次让AI干活前它都能按这套规范来执行。第一次用Skills的人容易犯的错是把SKILL.md写得像一本大而全的百科全书什么都说结果AI什么都没记住。真实有效的Skills应该是“一份能直接指导行为的操作手册”要明确命令、约束、输出格式。我建了一个叫vue3-migration的Skill内容大致包括角色设定告诉AI它是一名Vue3迁移专家熟悉form-generator的代码结构。背景信息简要说明这个项目是做什么的、升级范围在哪里、不能动哪些逻辑。规范约束明确禁止使用哪些Vue2 API遇到时应当如何改写。工作流步骤要求AI在处理任务时先读指定文档再逐文件改动每次改动后输出变更说明。输出格式要求AI用中文回复代码展示带文件路径复杂改动分步说明不要一次性输出过长的未经解释的代码块。配置好之后我在Trae对话里的体验变化非常明显。没有Skills时每次都要反复解释项目背景、约束条件AI还是容易给出泛泛的方案甚至会改到一半把不相关的逻辑动掉。有了SkillsAI相当于被“约束”在了这个项目的语境里回答质量和代码改动准确率提升了一个层级。4.2 一个典型任务的完整流程从“迁移某个mixin”到合入代码我用一个具体的例子说明整个流程是怎么转的。任务是升级upload-mixin.js这个mixin原本负责表单上传组件的数据处理和上传状态管理。我打开Trae的对话窗口新建子会话在输入框里直接描述任务“把src/mixins/upload-mixin.js迁移成Vue3的composable输出到src/composables/useUpload.js注意保持对外API不变upload方法参数和回调逻辑不能改。”因为已经加载了vue3-migration这个SkillTrae会自动理解它面对的是一个Vue3迁移任务会按照Skill里定义的步骤执行。它先读了这个mixin的完整代码然后给出迁移方案说明再写出新的useUpload.ts。整个过程中我可以随时打断追问比如我问“原来的success回调在composable里怎么传递更合理”AI会基于代码上下文给出方案。关键的一步是AI改完代码后我不会直接信任。我会让AI自己输出“这个改动涉及到哪些调用方、影响哪些组件”然后我再全局搜索原来的mixin引用确认没有遗漏。确认OK后才让AI执行替换文件、清理旧引用的操作。这里还说一个实操心得在Trae里不要一个会话干太多事。我一般一个子会话只处理“一个模块或一个主题”比如“迁移所有mixin”就太宽泛了AI容易漏细分到“迁移upload-mixin”这种粒度AI的专注度更高审查也更容易。一次任务结束我会要求AI总结变更摘要形成一条待测试清单方便后面统一回归。4.3 让Trae执行全局替换和批量修改的边界在哪里Trae在这种合并类项目里最强的其实是批量修改能力。比如全仓库的.sync改v-model:xxx、全局过滤器的调用替换、$listeners的改写这些工作如果手工做量大且容易漏AI帮你改就高效得多。但边界也明显批量修改容易出现误伤尤其是同名属性在不同文件里有不同含义时AI可能沿用统一策略导致问题。我的经验是全局替换类任务分两轮。第一轮让AI只做“找到全部”的工作输出所有需要改动的位置清单和匹配摘要不去改动。人工审一眼清单确认没有特殊情况或者告诉AI哪些位置排除。第二轮再让AI根据确认过的清单执行替换。这样虽然多花了一点时间但能最大程度避免AI过度自信地改坏代码。form-generator升级中我大概做了十几次这种批量操作只有一次因为某个组件里正好用了同名的自定义事件出现了小范围误改其他基本一次到位。另外每次AI批量改完我都会让Trae自动跑一遍项目的静态检查比如vue-tsc、eslint和关键页面的冒烟测试。Trae内置的终端可以执行命令AI能根据报错自动修复这个闭环很重要。没有这个闭环的话等合入代码再被CI拦下来定位问题的成本就高很多。4.4 Skills的迭代边升级边把新规范固化回去我这次升级过程中至少把vue3-migration这个Skill迭代了三版。一开始它只有泛泛的规范比如“禁止使用Vue2 API”但发现AI在执行中还经常用一些不太合适的模式比如把所有响应式数据都用reactive包一层、对简单数据类型也用reactive而不是ref。我就在Skill里加了明确说明“基础类型状态统一使用ref复杂嵌套数据才用reactive对象数组使用reactive或ref时保持一致性即可但不要混用导致行为不可预期。”再比如form-generator里有很多组件是函数式组件Vue3里函数式组件虽然还存在但性能优势和写法习惯都变了。AI第一次遇到时会纠结要不要保留。我在Skill里加了规则“函数式组件如果只是为了透传props和事件统一改写成普通组件如果确实需要无状态高性能渲染用defineComponent里的setup返回渲染函数。” 这就给了AI一个明确的决策依据不会每次都在那里反复权衡。Skills不只是给AI用的它也是团队知识沉淀的载体。升级做完之后我把这份SKILL.md留在了项目里新成员进来读一遍就能理解“这个项目升级过、当前有哪些写法约束、遇到某某类型问题怎么处理”比单独的文档更贴近实际开发语境。5. 升级过程中遇到的高频问题与解决方案实录5.1 常见报错与排查思路速查我整理了一份升级期间频繁遇到的报错和排查思路放在这里作为参考问题现象根因解决方案组件渲染后子组件数据不同步更新Vue3响应式特性变化$set未移除导致重复触发或数据未深度代理移除$set直接赋值检查对象是否被ref或reactive正确包裹事件总线$emit不再触发Vue3移除了$on/$off/$once统一改用mitt注意在onUnmounted时解绑监听编译报错slot-scope已废弃Vue3模板语法变更全局替换为v-slot动态插槽名使用中括号语法动态组件无法渲染resolveComponent未正确使用或组件未注册建立全局组件注册表用resolveComponent显式解析渲染函数里h函数报错Vue3的h函数需要从vue显式导入检查导入语句import { h } from vuev-model自定义参数不生效Vue3的v-model合并了.sync但参数名也需要调整统一使用v-model:propName子组件内使用update:propNameTypeScript编译报错Vue.prototype不存在Vue3全局API挂载方式变更使用app.config.globalProperties或改用依赖注入项目启动非常慢可能还保留了Webpack相关配置升级到Vite并检查依赖是否有Vue2版本混入5.2 一个隐蔽的坑defineComponent和Options API混用时的类型问题form-generator老代码里都是export default { ... }的对象写法。Vue3里这种对象写法本身还能用但在TypeScript场景下属性自动提示会丢。所以我让Trae分批把所有组件出口包了一层defineComponent。听起来简单实际操作时发现一个隐藏问题如果组件里使用了this.$refs.xxx访问子组件并且子组件是用defineComponent定义的TypeScript能正确推导但如果是老式对象$refs类型就很弱容易导致模板里调用方法时报错。这属于升级过程里“不报错但体验差”的类型。解决方案是在升级核心组件时顺手把defineComponent的泛型参数补上用defineComponentPropsType()的方式声明props类型让$refs和模板里的上下文推断更准确。这个过程靠AI也能完成前提是你在Skill里定义清楚目标。5.3 边界场景拖拽排序库的兼容问题form-generator的拖拽能力依赖一个老的拖拽库实际项目里用的vuedraggable。这个库升级Vue3后必须使用vuedraggable4版本API有变化比如list属性改成了modelValue拖拽结束事件名从end变成update:modelValue或change。这个坑比较经典我在升级时专门让AI检查了所有拖拽容器的绑定事件逐一替换否则会出现拖拽后列表不更新的问题。同时要注意vuedraggable4的内部实现依赖了sortablejs的版本如果你项目里对sortablejs有二次封装要确认没有同时存在多个版本否则会出现一些奇怪的拖动异常。建议统一锁定sortablejs的版本号避免依赖解析时出现重复实例。5.4 排查问题的效率秘诀把报错上下文完整丢给Trae升级过程中我遇到一个比较棘手的飞线——表单设计器里的子表单组件在拖入新行后该行绑定的校验规则没有实时生效但刷新后又有。这种“运行时状态异常”最难定位因为你不知道是响应式问题、事件触发问题还是渲染时序问题。我的排查方法是先把复现步骤、期望行为、实际行为以及相关组件的代码一起丢给Trae要求它“先别改代码按假设驱动的方式列出所有可能原因并按概率排序”。Trae会结合代码上下文整理出几条线索比如可能和v-for的key值有关、可能和深层响应式对象的监听时机有关、可能和组件内watch的flush时机有关。然后我按它的线索逐个验证最终定位到问题是子表单组件的watch默认在pre时机触发导致新增行数据还没更新完就执行了校验把flush: post加上就解决了。这个过程中Trae的价值不是替你猜答案而是提供了一套结构化的排查思路并且能快速调取相关代码片段。这也验证了“AI辅助编程”在复杂项目里的正确姿势它适合做知识检索、代码理解、方案枚举、批量改写而最终决策和逻辑确认还是需要人来完成。6. 用TraeSkills升级项目的整体复盘与实用建议整个form-generator升级Vue3的过程如果让我用一句话总结和传统手工迁移相比最大的变化不是“快”而是“试错成本变低了”。传统迁移中遇到不确定的API行为我可能得写段demo去验证或者在社区搜半天而在Trae里直接让AI基于代码上下文给我讲清楚这个API在新版本里的行为边界还能立刻改一段示例代码验证效果这个交互方式对迁移类项目极其友好。Skills的作用前期我低估了。最初我以为它只是一个“提示词预设”但实际用下来它更像一份项目级别的“军规”能把隐性知识显性化。尤其是在批量任务里它保证了AI的行为一致性——无论你开多少个会话AI对“什么是可以改的、什么是不能动的”都有统一的判断基准。这一点在多人协作或长时间项目里尤其重要。几个经验建议写给准备做类似事情的人迁移前先出问题清单把全仓库的Vue2特性扫描一遍让AI帮你生成施工图别急着改代码。Skills不要一次性写大而全边做边迭代把踩过的坑实时固化进去。一个会话干一件事任务粒度要细AI的完成质量和可审查性都会提升。批量替换不要一步到位先让AI列清单确认后再执行。每次改动后让AI自己跑一遍静态检查形成“改代码-检查-修复”的闭环不要攒一堆错误到最后才处理。我在实际开发和项目复盘里还有一个深切的感受像form-generator这种老项目代码里有很多“当时为了绕过某个Vue2限制而写出的绕行方案”在Vue3时代已经不再是问题。升级的真正价值不是把一个项目从旧版搬到新版而是借这个机会把那些历史包袱和绕行方案一并清掉。这种清理不是AI能独自完成的它需要人对业务逻辑的理解而AI的意义是帮你加快理解速度、降低清理成本。最后一小段实操补充如果你也想把Trae的Skills用在类似项目里建议先从一个很小的规范开始比如只规定“Vue2到Vue3的API替换对照表”然后跑几个小任务验证效果再逐步增加项目背景、代码约束、工作流步骤。不要一上来就追求完美Skills是长在真实任务上的越用才越顺手。这次升级结束了但这套“TraeSkills改造老项目”的工作方式我后面大概率会在其他项目里继续用毕竟尝过甜头之后再让我回头纯手工改代码确实有点回不去了。
返回列表