这份清单前七步列得挺全,我补几条同样高频、但最容易在上线后才炸的差异,接着你的顺序往下排。

生命周期与 this 的消失:`beforeDestroy/destroyed` 改名 `onBeforeUnmount/onUnmounted`,`errorCaptured`→`onErrorCaptured`,`activated/deactivated`→`onActivated/onDeactivated`;`beforeCreate/created` 没有对应钩子,直接在 setup 里写就行。`this` 没了之后:`this.$refs.foo` 要改成 `const foo = ref(null)` 同名声明;`this.$emit` 在 `<script setup>` 里是 `defineEmits`,`props` 是 `defineProps`;子组件方法想被父组件 ref 调用,记得 `defineExpose`。全局那块:`Vue.prototype.$http` → `app.config.globalProperties.$http`,`new Vue()` → `createApp()`。

几个静默不报错、但行为变了的坑:① `v-if` 和 `v-for` 同元素时优先级反转了,Vue 2 里 `v-for` 先执行、Vue 3 里 `v-if` 先执行,两者同时用基本必翻车,拆成两层标签最稳;② 过渡类名 `v-enter`/`v-leave` 改成 `v-enter-from`/`v-leave-from`,老 CSS 不改就是「动画没了但不报错」;③ 组件 `v-model` 默认 prop 从 `value` 变 `modelValue`、事件从 `input` 变 `update:modelValue`,`.sync` 语法没了,改成 `v-model:xxx`;④ `$listeners` 被合并进 `$attrs`,`v-on="$listeners"` 要改成 `v-bind="$attrs"`;⑤ filters 已移除,`keyCode` 修饰符(`@keyup.13`)也移除,用 `@keyup.enter`。

另外 mixin 是这套迁移里心智负担最大的一块,建议直接拆成 `useXxx()` 组合函数,反正迁移构建不会帮你处理 mixin 的作用域冲突。收尾时把 `@vue/compat` 从依赖里删干净,再挂上 eslint-plugin-vue 的 deprecated 规则扫一遍,比肉眼可靠。