Skip to content
错题本 0已完全掌握 0正在读取本地学习状态…
先想一想,再看答案

Vue 2/3 对比与迁移 ​

38. Vue 2 与 Vue 3 的核心区别怎么系统回答? ​

展开答案与追问

参考答案: 按响应式、组织方式、渲染优化、应用 API、类型支持与破坏性变更分层回答。Vue 3 使用 Proxy 与独立响应式能力,强化 Composition API、编译器辅助 patch 与 TypeScript 体验;Vue 2.7 已回移部分语法和 API,不能将所有 Composition API 能力都说成 Vue 3 独占。

追问与易错点: 下面对比表用于复习,真实迁移要按第三方依赖和项目版本逐项核对。迁移指南

39. 为什么 Vue 3 不需要 Vue.set? ​

展开答案与追问

参考答案: 对 reactive 返回的代理添加或删除属性可以被拦截,通常直接赋值或 delete 即可。关键是操作代理;如果绕到原始对象修改,不会自动经过该代理的拦截。Vue 2 则需要处理已观察对象无法侦测属性新增等限制。

追问与易错点: 不要把“无需 $set”理解成解构基本值、外部原始引用或任意 class 实例都会自动响应。

40. Vue 2 到 Vue 3 的组件 API 有哪些迁移点? ​

展开答案与追问

参考答案: 组件 v-model 默认由 value/input 改为 modelValue/update:modelValue;.sync 对应的场景转向带参数 v-model。事件声明用 emits,$listeners 合并进 $attrs,.native 被移除,插槽统一为函数。还需处理过滤器、实例事件总线和多根组件透传。

追问与易错点: 迁移不是简单全局替换字符串,要确认组件库契约和自动透传行为。破坏性变更

41. 为什么 createApp 比全局 Vue API 更容易隔离? ​

展开答案与追问

参考答案: Vue 2 常通过构造器上的全局配置与插件影响实例;Vue 3 使用 createApp 创建应用,app.use、app.component 等配置以应用为边界,利于同页多应用和测试隔离。模块级可变单例依然可能泄漏跨应用或 SSR 请求状态。

追问与易错点: Vue 3 的应用隔离不是对用户代码中所有共享变量自动隔离。

42. 实际项目如何从 Vue 2 迁移到 Vue 3? ​

展开答案与追问

参考答案: 先盘点 Vue、Router、状态管理、UI 库、构建与测试版本和破坏性 API;建立关键业务回归;评估 @vue/compat 并按警告修复,或按应用边界分阶段切换;最后移除兼容配置、验收性能与行为。

追问与易错点: 不必同时重写全部 Options API。兼容构建有明确限制,不能保证所有 Vue 2 插件直接运行。兼容构建

43. Pinia/Vuex 与普通 reactive 单例有什么区别? ​

展开答案与追问

参考答案: 普通单例可提供共享响应式数据,但调试、模块契约、插件、测试隔离及 SSR 生命周期需要自行设计。Pinia/Vuex 提供更明确的状态组织与工具支持;选型应结合既有项目,不是数据放入 store 就自动性能更好。

追问与易错点: 解构 Pinia store 的响应式状态时可用 storeToRefs;actions 可直接解构。SSR 要按请求隔离状态。Pinia 核心概念

速查表与代码示例 ​

Vue 2 / Vue 3 对比表 ​

维度Vue 2 常见机制Vue 3 常见机制回答边界
对象响应式defineProperty 逐属性处理Proxy 拦截对象操作,ref 跟踪 valueVue 2.7 仍沿用 Vue 2 响应式底层
属性新增/删除需要 set/delete 等辅助方式操作响应式代理可直接捕获绕过代理操作原对象不同
数组封装变更方法,索引/length 有限制代理并配合数组专门处理原生数组行为还需响应式工具适配
Map/Set不具备 Vue 3 同等集合响应支持有集合类型的响应式处理不是任意宿主或内建对象都适用
逻辑组织Options API 为主支持 Options / CompositionVue 2.7 也有 Composition API
应用入口new Vue 与全局配置createApp 与应用级配置业务模块单例仍需自行隔离
根节点模板通常单根支持 Fragment 多根多根时 attrs 透传需明确目标
组件 v-model默认 value / input默认 modelValue / update:modelValue支持带参数多个 v-model
生命周期beforeDestroy / destroyedbeforeUnmount / unmountedsetup 不是 created 简单改名
渲染优化VNode 与运行时 Diff编译提示、静态优化、Block 等Vue 2 也有编译优化,非完全没有
keyed 列表中间段常见双端比较索引映射及 LIS 减少移动不代表任意输入都必然走相同路径
TS 体验可用,但选项式推断有约束更适配类型推断和组合式逻辑编译类型不替代接口运行时校验
迁移 APIfilters、$on/$off 等旧用法移除部分旧 API,改用函数/显式订阅需核对 UI 库和插件兼容

对比依据:Vue 2 响应式说明、Vue 2.7 说明、Vue 3 迁移指南。

生命周期速查 ​

阶段/目的Vue 2 Options APIVue 3 Options APIVue 3 Composition API
初始化前后beforeCreate / createdbeforeCreate / createdsetup 中组织初始化,无 onCreated
挂载前beforeMountbeforeMountonBeforeMount
挂载后mountedmountedonMounted
更新前beforeUpdatebeforeUpdateonBeforeUpdate
更新后updatedupdatedonUpdated
卸载前beforeDestroybeforeUnmountonBeforeUnmount
卸载后destroyedunmountedonUnmounted
缓存激活/停用activated / deactivatedactivated / deactivatedonActivated / onDeactivated
后代错误捕获errorCapturederrorCapturedonErrorCaptured
SSR 数据预取serverPrefetch(支持版本)serverPrefetchonServerPrefetch

Vue 3 的 mounted/updated/unmounted 一类客户端钩子不在 SSR 运行;setup/创建阶段需避免无清理机会的浏览器副作用。onErrorCaptured 不替代所有异步错误处理。详细语义见 生命周期 API。

示例:Vue 3 监听参数、清理请求与使用 computed ​

vue
<script setup>
import { computed, ref, watch } from 'vue';

const props = defineProps({ userId: { type: String, required: true } });
const user = ref(null);
const loading = ref(false);
const error = ref('');
const displayName = computed(() => user.value?.name ?? '暂无用户');

watch(() => props.userId, async (id, _oldId, onCleanup) => {
  const controller = new AbortController();
  let active = true;
  // 在 await 前注册,覆盖源变化和侦听器停止时的清理。
  onCleanup(() => {
    active = false;
    controller.abort();
  });
  loading.value = true;
  error.value = '';
  user.value = null;
  try {
    const response = await fetch(`/api/users/${encodeURIComponent(id)}`, {
      signal: controller.signal,
    });
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();
    if (active) user.value = data;
  } catch (err) {
    if (active) error.value = String(err);
  } finally {
    if (active) loading.value = false;
  }
}, { immediate: true });
</script>

<template>
  <p v-if="loading">加载中</p>
  <p v-else-if="error" role="alert">{{ error }}</p>
  <p v-else>{{ displayName }}</p>
</template>

讲解重点:getter 监听 prop,computed 只派生展示;清理阻止旧结果写入,也保护 finally 不会清除新请求的 loading。示例使用第三参数 onCleanup,避免把 3.5+ 的 onWatcherCleanup 误当作所有 Vue 3 版本都可用。本例面向客户端,不包含 SSR 缓存或路由加载集成。

渲染更新概念图 ​

Vue 2 也具备模板编译、VNode 和异步更新,图中的整体链路并非 Vue 3 独占。Vue 3 编译优化细节见 渲染机制。

建议复习顺序 ​

  • 第一轮:1~19 题,掌握 API、组件契约和侦听边界。
  • 第二轮:20~26 题,串起生命周期、缓存与路由复用。
  • 第三轮:27~37 题,解释依赖跟踪、编译优化与 Diff。
  • 第四轮:38~43 题,结合对照表准备 Vue 2/3 迁移回答。

先尝试回答,再展开答案。每天进步一点。