Vue3 相比 Vue2 最大的变化是什么?

  • 响应式从 Object.defineProperty 改为基于 Proxy,对象新增、删除属性也能被追踪。
  • 新增 Composition API,更适合复杂逻辑复用和大型项目组织。
  • 编译器、运行时、Tree-shaking、TypeScript 支持都有明显提升。
  • Vue3 还引入了 Fragment、Teleport、Suspense、多个根节点等能力。

Vue3 为什么使用 Proxy 做响应式?

  • Proxy 可以代理整个对象,不需要像 Vue2 那样递归劫持每个属性。
  • 它能监听属性新增、删除、inownKeys 等操作。
  • 对数组下标和 length 的处理也更自然。
  • 缺点是无法兼容 IE11。

Vue3 响应式的基本流程是什么?

  • 读取响应式数据时,通过 track 收集当前副作用函数。
  • 修改响应式数据时,通过 trigger 找到依赖并触发更新。
  • 组件渲染本质上也是一个响应式副作用。
  • 依赖收集依赖“读取”,没有读取过的数据变化不会触发当前组件更新。

reactive 和 ref 有什么区别?

  • reactive 通常用于对象、数组、Map、Set 等复杂数据。
  • ref 可以包装任意值,基本类型必须用 ref 才能响应式。
  • ref 在 JS 中访问要 .value,模板中会自动解包。
  • 组合式函数返回状态时,ref 更容易保持解构后的响应式。

为什么 ref 在模板里不用写 .value?

  • Vue 模板编译时会自动解包顶层 ref。
  • 这样模板写法更接近普通变量。
  • 在 JavaScript 逻辑中仍然需要 .value,因为 ref 本身是一个对象。

reactive 解构后为什么可能丢失响应式?

  • 解构会把属性值取出来,脱离原始代理对象。
  • 如果解构的是普通值,后续不会再触发代理的 getter。
  • 可以使用 toReftoRefs 或直接保留对象访问。

toRef 和 toRefs 有什么用?

  • toRef 可以把响应式对象的某个属性转成 ref。
  • toRefs 可以把响应式对象的多个属性都转成 ref。
  • 常用于解构 reactive 状态,同时保持属性响应式。

shallowRef 和 ref 的区别?

  • ref 会让对象内部也变成深层响应式。
  • shallowRef 只追踪 .value 本身的替换,不深度代理内部对象。
  • 适合大型对象、第三方实例、图表实例、编辑器实例等场景。

shallowReactive 和 reactive 的区别?

  • reactive 是深层响应式。
  • shallowReactive 只代理对象第一层属性。
  • 适合只需要追踪顶层变化的大对象,能减少不必要的响应式开销。

markRaw 有什么用?

  • markRaw 可以标记对象永远不被转成响应式代理。
  • 常用于第三方类实例、图表实例、地图实例、复杂不可代理对象。
  • 它能减少性能开销,也能避免代理破坏第三方库内部逻辑。

toRaw 有什么用?

  • toRaw 可以拿到响应式代理背后的原始对象。
  • 适合临时调试、和第三方库交互、避免代理对象参与某些比较。
  • 不建议长期持有 raw 对象并直接修改,否则会绕过响应式系统。

isRef、isReactive、isProxy 有什么区别?

  • isRef 判断一个值是不是 ref。
  • isReactive 判断一个对象是不是 reactive 创建的响应式代理。
  • isProxy 判断一个对象是不是 readonly 或 reactive 创建的代理。

computed 和 methods 有什么区别?

  • computed 有缓存,依赖不变时不会重新计算。
  • methods 每次调用都会执行。
  • 模板中复杂表达式建议放 computed,事件行为和主动调用逻辑放 methods。

computed 和 watch 有什么区别?

  • computed 用于根据依赖计算出新值,更偏“派生状态”。
  • watch 用于观察数据变化后执行副作用,比如请求、缓存、日志。
  • computed 有缓存并应保持纯净,watch 可以处理异步和副作用。

Vue3.4 中 computed 的 previous value 是什么?

  • Vue 3.4+ 支持在 computed getter 中获取上一次返回值。
  • 它适合“超过阈值后保留上一次合法结果”的场景。
  • 这个能力不要滥用,普通派生计算仍然只依赖当前状态即可。

watch 和 watchEffect 有什么区别?

  • watch 明确指定监听源,只有源变化才执行回调。
  • watchEffect 会自动收集同步执行过程中读取到的依赖。
  • watch 更可控,适合精确监听;watchEffect 更方便,适合快速同步副作用。

watch 的 immediate 有什么作用?

  • immediate: true 会让 watch 在初始化时立即执行一次。
  • 常用于进入页面立即根据参数请求数据。
  • 不设置时,watch 默认等监听源第一次变化后才执行。

watch 的 deep 有什么作用?

  • deep: true 会深度监听对象内部变化。
  • 深度监听对象大时会有性能成本。
  • Vue 3.5+ 的 deep 可以传数字,用来限制监听深度。

watch 的 flush 有哪些取值?

  • pre 是默认值,组件 DOM 更新前执行。
  • post 在组件 DOM 更新后执行,适合读取更新后的 DOM。
  • sync 同步触发,使用要谨慎,可能影响性能。

onWatcherCleanup 有什么用?

  • Vue 3.5+ 提供 onWatcherCleanup 用于注册 watcher 失效时的清理逻辑。
  • 常用于取消过期请求、清理异步任务。
  • 比在复杂 watch 回调中手动管理取消逻辑更清晰。

effectScope 有什么用?

  • effectScope 可以收集一组响应式副作用。
  • 调用 stop 后可以一次性停止这一组 computed、watch、watchEffect。
  • 适合插件、组合式函数、动态创建逻辑的统一清理。

nextTick 的作用是什么?

  • nextTick 会等 DOM 更新完成后再执行回调。
  • Vue 状态变化后 DOM 不是立即同步更新,而是异步批量更新。
  • 需要读取更新后的 DOM 尺寸、滚动位置时常用。

Vue 为什么要异步更新 DOM?

  • 多次状态变化可以合并成一次 DOM 更新。
  • 避免重复渲染,提高性能。
  • 这也是为什么修改状态后立刻读 DOM 可能读到旧结果。

Composition API 解决了什么问题?

  • 让逻辑可以按功能聚合,而不是被 data、methods、watch 分散。
  • 更方便抽取和复用逻辑。
  • 对 TypeScript 推导更友好。
  • 大型组件中代码组织更清晰。

Options API 和 Composition API 怎么选择?

  • 简单页面用 Options API 也完全可以。
  • 复杂业务、逻辑复用、TypeScript 项目更适合 Composition API。
  • 团队项目要统一风格,不建议一个模块里混用太乱。

setup 执行时机是什么?

  • setup 在组件创建阶段执行,早于 Options API 的大多数选项。
  • 此时还没有组件实例的 this
  • 里面可以创建响应式状态、注册生命周期、返回模板需要的数据。

setup 中为什么没有 this?

  • Composition API 不依赖组件实例上的 this
  • 这样逻辑更接近普通函数,也更利于 TypeScript 推导。
  • 需要路由、store 等能力时,通过对应的组合式 API 获取。

script setup 有什么优势?

  • 语法更简洁,顶层变量和函数可以直接在模板中使用。
  • 编译期宏让 props、emits、model 等声明更方便。
  • TypeScript 类型推导体验更好。

script setup 中 defineProps 是什么?

  • defineProps 是编译期宏,用于声明组件 props。
  • 它不需要手动 import。
  • 支持运行时声明,也支持 TypeScript 类型声明。

script setup 中 defineEmits 是什么?

  • defineEmits 用于声明组件可以触发的事件。
  • 它能约束事件名称和参数类型。
  • 对组件库和大型项目的事件维护很有帮助。

defineExpose 有什么用?

  • <script setup> 默认不会暴露内部变量给父组件 ref。
  • defineExpose 可以显式暴露需要给外部访问的方法或状态。
  • 适合弹窗、表单、播放器等需要命令式调用的组件。

defineOptions 有什么用?

  • defineOptions 可以在 <script setup> 中声明组件选项。
  • 比如 nameinheritAttrs 等。
  • 它减少了额外写一个普通 <script> 的需求。

defineSlots 有什么用?

  • defineSlots 用于给 slots 做类型声明。
  • 常见于 TypeScript 组件库。
  • 它提升插槽参数的类型提示和使用体验。

defineModel 解决了什么问题?

  • defineModel 简化了自定义组件支持 v-model 的写法。
  • Vue 3.4 起它已经稳定。
  • 它可以减少手写 modelValue props 和 update:modelValue emits 的模板代码。

defineModel 和传统 v-model 写法有什么区别?

  • 传统写法需要声明 modelValueupdate:modelValue
  • defineModel 会帮你生成对应的 prop 和 emit。
  • 多个 v-model 或修饰符场景也可以更集中处理。

Vue3.5 响应式 props 解构是什么?

  • Vue 3.5+ 中,defineProps 解构出来的变量在同一个 <script setup> 中仍然保持响应式。
  • 编译器会自动把访问转换成 props.xxx
  • 这让 props 默认值和解构写法更自然。

useTemplateRef 有什么用?

  • Vue 3.5+ 提供 useTemplateRef 获取模板 ref。
  • 它比手写 const el = ref(null) 再绑定同名 ref 更明确。
  • 适合 DOM 引用和子组件实例引用。

v-bind 同名简写是什么?

  • Vue 3.4+ 支持 :id 等同名简写。
  • 例如 :id="id" 可以写成 :id
  • 适合属性名和变量名一致的场景。

Vue3 的生命周期有哪些?

  • 常用有 onMountedonUpdatedonUnmounted
  • 还有 onBeforeMountonBeforeUpdateonBeforeUnmount
  • 组合式 API 中生命周期以函数形式调用。

onMounted 适合做什么?

  • 适合访问 DOM、初始化第三方库、发起首屏客户端请求。
  • SSR 场景下,onMounted 只会在客户端执行。
  • 不要把能在 setup 中完成的纯计算都放进 mounted。

onUnmounted 适合做什么?

  • 清理定时器、事件监听、订阅、第三方实例。
  • 防止组件卸载后仍然占用资源。
  • onMounted 中的初始化逻辑通常成对出现。

Vue3 中父子组件通信方式有哪些?

  • 父传子使用 props。
  • 子传父使用 emit。
  • 跨层级可以用 provide/inject。
  • 复杂全局状态可以用 Pinia。

provide/inject 适合什么场景?

  • 适合跨层级传递稳定配置或上下文。
  • 比如主题、表单上下文、组件库配置、树组件上下文。
  • 不建议用它替代所有全局状态管理。

provide/inject 是响应式的吗?

  • 如果 provide 的是 ref 或 reactive 对象,inject 后仍然可以保持响应式。
  • 如果 provide 普通值,本身不会自动变成响应式。
  • 最好把修改方法也由 provider 提供,避免下层随意修改。

attrs 有什么用?

  • attrs 接收没有被 props 声明的 attribute。
  • 常用于组件透传原生属性、事件、class、style。
  • 多根节点组件中需要手动指定 attrs 绑定到哪个根节点。

inheritAttrs 有什么用?

  • inheritAttrs: false 可以关闭 attrs 自动继承到根节点。
  • 适合组件内部需要精确控制属性落点。
  • 常见于封装 Input、Button、FormItem 等基础组件。

slot 有什么用?

  • slot 用来把父组件内容传给子组件指定位置渲染。
  • 默认插槽适合普通内容分发。
  • 具名插槽适合布局多个区域。

作用域插槽是什么?

  • 子组件可以通过 slot props 把数据传给父组件的插槽内容。
  • 父组件决定 UI,子组件提供数据。
  • 表格列、自定义列表项、弹窗底部按钮都常用。

动态组件是什么?

  • 使用 <component :is="xxx" /> 根据状态切换组件。
  • 适合 tab、动态表单、低代码渲染等场景。
  • 配合 keep-alive 可以缓存组件状态。

keep-alive 有什么用?

  • keep-alive 可以缓存组件实例,避免切换时销毁重建。
  • 常用于 tab 页、路由页面缓存。
  • 可以使用 include、exclude、max 控制缓存范围。

activated 和 deactivated 什么时候触发?

  • 被 keep-alive 缓存的组件激活时触发 activated
  • 从页面切走但未销毁时触发 deactivated
  • 适合恢复滚动、暂停轮询、刷新缓存数据。

Teleport 有什么用?

  • Teleport 可以把组件内容渲染到 DOM 树的其他位置。
  • 常用于 Modal、Drawer、Tooltip、Toast。
  • 它解决了层级、overflow、z-index 等布局问题。

Suspense 有什么用?

  • Suspense 用来处理异步组件或异步 setup 的等待状态。
  • 可以统一展示 fallback。
  • 在 SSR 和异步组件场景中更有价值。

Vue3 支持多个根节点吗?

  • 支持。
  • Vue2 组件模板只能有一个根节点,Vue3 引入 Fragment 后允许多个根节点。
  • 多根节点时 attrs 不会自动知道绑定到哪里,需要手动处理。

v-if 和 v-show 的区别?

  • v-if 控制元素是否创建和销毁。
  • v-show 控制 CSS 的 display 显隐。
  • 频繁切换用 v-show,条件很少变化用 v-if。

v-for 和 v-if 为什么不建议写在同一个元素上?

  • 可读性差,优先级和过滤逻辑容易混乱。
  • 建议先用 computed 过滤列表,再 v-for 渲染。
  • 或者把 v-if 放到外层容器上。

v-model 在组件上是什么原理?

  • 默认对应 modelValue prop 和 update:modelValue 事件。
  • 父组件传入值,子组件 emit 更新。
  • 本质仍然是 props 向下、事件向上。

多个 v-model 怎么写?

  • 可以使用 v-model:titlev-model:visible 等参数。
  • 子组件对应声明 titlevisible prop 和 update:titleupdate:visible 事件。
  • Vue3 中 defineModel 可以简化这类写法。

v-model 修饰符怎么处理?

  • 内置修饰符有 .lazy.number.trim
  • 自定义组件可以读取 model modifiers 并自行处理。
  • defineModel 对修饰符支持更友好。

v-once 有什么用?

  • v-once 只渲染一次,后续响应式更新不会影响它。
  • 适合完全静态且不再变化的内容。
  • 用错会导致页面不更新。

v-memo 有什么用?

  • v-memo 可以基于依赖数组跳过部分模板更新。
  • 适合大列表中局部项更新优化。
  • 使用前应先确认性能瓶颈,不要盲目加。

Vue 中 key 的作用是什么?

  • key 用于标识 vnode 身份,帮助 diff 正确复用节点。
  • 动态列表必须使用稳定唯一 key。
  • 切换组件时改变 key 可以强制重建组件。

Vue 模板编译做了什么?

  • 模板会被编译成 render 函数。
  • 编译器会生成静态提升、patch flag、事件缓存等优化信息。
  • 这些信息帮助运行时更精确地更新 DOM。

Vue 的 patch flag 是什么?

  • patch flag 是编译器标记动态节点类型的提示。
  • 运行时可以根据 flag 更快定位需要更新的部分。
  • 这是 Vue3 编译时优化的重要部分。

静态提升是什么?

  • 静态提升会把不依赖响应式数据的 vnode 提升到 render 外部。
  • 避免每次渲染都重新创建静态节点。
  • 它提升了模板渲染性能。

Vue3 的响应式为什么比 Vue2 更完善?

  • Vue3 可以追踪对象属性新增和删除。
  • 可以更好处理数组、Map、Set 等结构。
  • 响应式系统独立成包,也更容易在非组件场景使用。

Vue3 中数组响应式要注意什么?

  • 数组下标、length、push、splice 等都能被响应式追踪。
  • 大数组频繁深层代理可能有性能成本。
  • 如果只是展示大数组,可以考虑 shallowRef、分页或虚拟列表。

Vue3 中 Map 和 Set 是响应式的吗?

  • reactive 包装 Map、Set 后可以追踪增删改查。
  • 读取 size、迭代 keys/values 也会收集相关依赖。
  • 大型集合频繁操作时仍要关注性能。

Vue3 中 readonly 有什么用?

  • readonly 创建只读代理,防止外部直接修改。
  • 常用于暴露状态给外部消费,但不允许外部写入。
  • 修改 readonly 对象会在开发环境给出警告。

Vue3 中 shallowReadonly 有什么用?

  • shallowReadonly 只让第一层只读。
  • 深层对象仍然可以被修改。
  • 适合只想约束顶层 API 的场景。

Pinia 是什么?

  • Pinia 是 Vue 官方推荐的状态管理库。
  • 它类型推导友好,API 简洁,支持模块化 store。
  • 相比 Vuex,它更适合 Vue3 和 Composition API。

Pinia 和 Vuex 有什么区别?

  • Pinia 没有 mutations,直接通过 actions 或 store 实例修改状态。
  • Pinia 对 TypeScript 支持更自然。
  • Pinia 的 store 是模块化设计,不需要嵌套 modules。

Pinia 的 state、getters、actions 分别是什么?

  • state 保存状态。
  • getters 类似计算属性,用来派生状态。
  • actions 封装同步或异步业务逻辑。

Pinia 中如何解构 store 保持响应式?

  • 直接解构 store 属性可能丢失响应式。
  • 应使用 storeToRefs(store) 解构 state 和 getters。
  • actions 可以直接解构,因为它们本身是函数。

Pinia 持久化怎么做?

  • 可以监听 store 变化后写入 localStorage。
  • 也可以使用成熟的持久化插件。
  • 需要注意敏感信息不要随意存在本地。

Pinia 适合保存所有数据吗?

  • 不适合。
  • Pinia 适合客户端共享状态,比如用户信息、权限、主题、购物车。
  • 接口缓存、分页、重试等服务端状态可以考虑请求缓存方案。

Vue Router 4 和 Vue3 是什么关系?

  • Vue Router 4 是 Vue3 对应的官方路由库。
  • 它支持 Composition API,如 useRouteruseRoute
  • 路由配置、导航守卫、懒加载等仍然是核心能力。

useRouter 和 useRoute 有什么区别?

  • useRouter 获取路由实例,用于跳转、replace、back 等操作。
  • useRoute 获取当前路由对象,用于读取 params、query、meta。
  • 不要监听整个 route 对象,建议监听具体字段。

为什么不建议 watch 整个 route?

  • route 是响应式对象,整体监听容易触发过多。
  • 通常只关心 route.params.idroute.query.xxx
  • 精确监听更清晰,也能减少不必要逻辑执行。

Vue Router 中 hash 和 history 有什么区别?

  • hash 使用 #,服务端无需特殊配置。
  • history URL 更美观,但生产环境需要服务端配置 fallback 到 index.html。
  • 选择时要看部署环境是否支持 history fallback。

路由懒加载怎么写?

  • 使用动态 import:() => import('./views/Home.vue')
  • 它可以把不同页面拆成独立 chunk。
  • 首屏不需要的页面不会进入主包。

路由守卫有哪些?

  • 全局守卫:beforeEachbeforeResolveafterEach
  • 路由独享守卫:beforeEnter
  • 组件内守卫:onBeforeRouteLeaveonBeforeRouteUpdate

onBeforeRouteLeave 有什么用?

  • 在当前组件对应路由离开前执行。
  • 常用于未保存表单离开确认。
  • 返回 false 可以取消导航。

onBeforeRouteUpdate 有什么用?

  • 当前组件复用但路由参数变化时执行。
  • 例如 /user/1 切到 /user/2,组件不销毁但数据要重新请求。
  • 可以避免只在 mounted 中请求导致数据不更新。

路由 meta 适合放什么?

  • 页面标题、权限标识、是否缓存、布局类型等。
  • meta 不应该放大量业务数据。
  • 权限校验可以基于 meta.requiresAuth、meta.roles 等字段实现。

Vite 相比 Vue CLI 有什么优势?

  • 开发环境基于原生 ESM,启动更快。
  • HMR 更新更快。
  • 构建基于 Rollup,产物优化能力强。
  • Vue3 新项目通常优先选择 Vite。

Vite 的 dev server 为什么快?

  • 它按需转换模块,不需要启动时打包整个项目。
  • 浏览器通过原生 ESM 加载依赖。
  • 依赖预构建减少 CommonJS 和大量小模块带来的开销。

Vite 环境变量怎么使用?

  • 客户端可访问变量必须以 VITE_ 开头。
  • 通过 import.meta.env 读取。
  • 不要把密钥放到前端环境变量中。

Vue3 项目为什么常配合 TypeScript?

  • Composition API 和 <script setup> 对 TS 推导友好。
  • props、emits、store、路由、接口类型都能受益。
  • 大型项目中 TS 能提升重构安全性。

Vue3 中 props 如何做类型声明?

  • 可以使用运行时对象声明。
  • 也可以在 <script setup lang="ts"> 中用泛型声明。
  • 类型声明更适合复杂 TS 项目,运行时声明更直接。

withDefaults 有什么用?

  • 在类型方式声明 props 时,withDefaults 可以给 props 设置默认值。
  • Vue3.5 响应式 props 解构后,也可以使用 JS 默认值语法。
  • 选择哪种方式看项目 Vue 版本和团队习惯。

Vue3 中 emits 为什么要声明?

  • 声明 emits 能明确组件对外事件 API。
  • 可以获得事件名和参数类型提示。
  • 也能避免未知事件被错误地透传到根元素。

组件库中如何设计 Button 组件?

  • 要考虑 type、size、disabled、loading、icon、block 等常用 props。
  • 原生 button 属性和事件要合理透传。
  • loading 时要避免重复点击。
  • 样式要支持主题变量和可访问性。

组件库中如何设计 Input 组件?

  • 支持 v-model、placeholder、disabled、readonly、clearable。
  • 事件要区分 input、change、focus、blur。
  • 要支持表单校验状态和可访问性关联。
  • 组合式封装时注意 attrs 透传到真实 input。

组件库中如何设计 Modal 组件?

  • 使用 Teleport 挂载到 body。
  • 支持 v-model 控制显示隐藏。
  • 处理遮罩点击、Esc 关闭、滚动锁定、焦点管理。
  • 注意动画结束后再销毁内容。

Vue3 中如何封装组合式函数?

  • 函数名通常以 use 开头。
  • 内部可以使用 ref、computed、watch、生命周期。
  • 返回 ref 或方法,让调用方自由组合。
  • 要考虑清理逻辑,避免内存泄漏。

组合式函数和 mixin 有什么区别?

  • 组合式函数来源清晰,返回值明确。
  • mixin 容易命名冲突,数据来源不直观。
  • Composition API 基本替代了大部分 mixin 复用场景。

VueUse 是什么?

  • VueUse 是一组常用 Composition API 工具函数集合。
  • 包含浏览器 API、传感器、状态、动画、网络等能力封装。
  • 使用前要评估体积、维护和是否真的需要。

如何封装 useDebounce?

import { ref, watch } from 'vue'

export function useDebounce(source, delay = 300) {
const value = ref(source.value)

watch(source, newValue => {
const timer = setTimeout(() => {
value.value = newValue
}, delay)

return () => clearTimeout(timer)
})

return value
}

如何封装 useToggle?

import { ref } from 'vue'

export function useToggle(defaultValue = false) {
const value = ref(defaultValue)
const toggle = () => {
value.value = !value.value
}

return [value, toggle]
}

如何封装 useRequest?

  • 至少要包含 loading、data、error、run。
  • 要处理重复请求、参数变化、组件卸载。
  • 如果项目接口场景复杂,可以使用成熟请求库或缓存库。

Vue3 中如何做权限控制?

  • 登录态控制用户是否能进入系统。
  • 路由守卫控制页面访问。
  • 菜单根据权限动态生成。
  • 按钮权限控制操作入口。
  • 后端接口权限才是真正安全边界。

Vue3 中如何做动态路由?

  • 登录后根据权限获取菜单或路由配置。
  • 使用 router.addRoute 动态添加路由。
  • 刷新页面时要重新恢复动态路由。
  • 404 路由通常要在动态路由之后处理。

Vue3 中如何做路由缓存?

  • 使用 keep-alive 包裹 router-view。
  • 根据路由 meta 控制 include、exclude。
  • 注意缓存页面的数据刷新和滚动位置恢复。

Vue3 中如何处理大列表?

  • 使用分页、懒加载或虚拟列表。
  • 不需要响应式的大数据可以用 shallowRef 或 markRaw。
  • 列表项组件要使用稳定 key。
  • 避免每一项都绑定复杂计算和大量事件。

Vue3 性能优化有哪些方向?

  • 路由懒加载、组件懒加载、第三方库按需引入。
  • 使用 v-memo、v-once、computed 缓存合适数据。
  • 大列表虚拟滚动。
  • 图片懒加载、资源压缩、CDN、缓存。
  • 使用 Devtools 和性能面板先定位再优化。

Vue3 中如何减少不必要的响应式开销?

  • 大对象使用 shallowRef、shallowReactive。
  • 第三方实例使用 markRaw。
  • 不需要响应式的数据不要放进 reactive/ref。
  • 避免深度 watch 大对象。

Vue3 中如何避免内存泄漏?

  • 组件卸载时清理定时器、事件监听、订阅。
  • 第三方实例要 destroy。
  • 异步请求要处理取消或过期结果。
  • keep-alive 页面要考虑 deactivated 中暂停副作用。

Vue Devtools 能做什么?

  • 查看组件树、props、state、Pinia store。
  • 追踪组件更新和事件。
  • 调试性能和状态变化。
  • Pinia 和 Vue Router 都能和 Devtools 集成。

Vue3 SSR 是什么?

  • SSR 是服务端把 Vue 组件渲染成 HTML。
  • 优点是首屏和 SEO 更好。
  • 缺点是服务端压力、同构复杂度和 hydration 问题。

Hydration 是什么?

  • Hydration 是客户端接管服务端 HTML 的过程。
  • 服务端和客户端渲染结果不一致会产生 hydration mismatch。
  • 时间、随机数、浏览器 API、环境差异是常见原因。

Vue3 中如何避免 Hydration mismatch?

  • 不要在首屏渲染中直接使用随机数或当前时间。
  • 浏览器专属逻辑放到 mounted 后执行。
  • 保证服务端和客户端初始数据一致。
  • 组件库要注意 SSR 兼容。

Nuxt 和 Vue 的关系是什么?

  • Vue 是 UI 框架,Nuxt 是基于 Vue 的应用框架。
  • Nuxt 提供路由、SSR、SSG、数据获取、部署等工程能力。
  • 面试中要分清 Vue 本身能力和 Nuxt 框架能力。

Vue3 中如何做 SEO?

  • 内容站优先考虑 SSR 或 SSG。
  • 设置 title、description、Open Graph 等 meta。
  • 路由动态页面要保证爬虫能拿到主要内容。
  • SPA 纯客户端渲染对 SEO 不友好。

Vue3 中如何做错误处理?

  • 组件错误可以使用 app.config.errorHandler
  • 异步请求错误要统一拦截和提示。
  • 路由错误、资源加载错误、Promise 未捕获错误也要监控。
  • 生产环境建议接入 Sentry 等监控平台。

Vue3 中 app.config.globalProperties 有什么用?

  • 可以注册全局属性,组件中通过实例访问。
  • 适合少量全局工具或兼容老项目。
  • 新项目更推荐显式 import 或 provide/inject,减少隐式依赖。

Vue 插件的 install 方法做什么?

  • 插件通过 install(app, options) 接收应用实例。
  • 可以注册全局组件、指令、provide、全局属性。
  • 插件适合封装通用能力,但不要滥用全局污染。

自定义指令适合什么场景?

  • 适合直接操作 DOM 的复用逻辑。
  • 比如权限按钮、自动聚焦、点击外部关闭、懒加载。
  • 如果能用组件或组合式函数解决,不一定需要指令。

Vue3 自定义指令有哪些生命周期?

  • 常用有 mountedupdatedunmounted
  • 也有 createdbeforeMountbeforeUpdatebeforeUnmount
  • 指令中要记得清理事件监听。

Vue3 中如何实现点击外部关闭?

  • 可以封装自定义指令。
  • mounted 时监听 document click。
  • 判断点击目标是否在当前元素内部。
  • unmounted 时移除监听,避免泄漏。

scoped CSS 的原理是什么?

  • Vue 会给组件 DOM 添加类似 data-v-xxx 的属性。
  • CSS 选择器也会被编译成带这个属性的选择器。
  • 这样能限制样式只影响当前组件。

scoped CSS 如何影响子组件?

  • scoped 默认只影响当前组件模板中的元素。
  • 要影响子组件内部元素,需要使用深度选择器。
  • 深度选择器要谨慎使用,避免破坏组件封装。

:deep() 有什么用?

  • :deep() 用于 scoped 样式中穿透子组件样式。
  • 常用于覆盖第三方组件库内部样式。
  • 过多使用说明主题定制方式可能不够规范。

:slotted() 有什么用?

  • :slotted() 用于给插槽传入内容设置样式。
  • 它只作用于插槽内容的根元素。
  • 适合组件库中控制 slot 内容外观。

CSS 变量在 Vue 组件中怎么用?

  • 可以在 style 中使用 CSS 自定义属性。
  • Vue SFC 支持 v-bind() 把 JS 变量注入 CSS。
  • 适合动态主题、动态尺寸、状态色。

Vue3 中如何做主题切换?

  • 可以基于 CSS 变量实现主题 token。
  • 切换根节点 class 或 data-theme。
  • 主题配置可以放 Pinia 或 localStorage。
  • 要同时考虑暗色模式和组件库变量。

Vue3 中如何处理国际化?

  • 常用 vue-i18n。
  • 文案不要硬编码在组件逻辑里。
  • 日期、货币、数字、复数和时区都要考虑。
  • 多语言路由和 SEO 也要提前设计。

Vue3 中如何组织项目目录?

  • 常见目录有 views、components、router、stores、api、utils、composables。
  • 通用组件和业务组件要区分。
  • 大型项目可以按业务模块拆分。
  • 目录结构要服务团队协作,而不是越复杂越好。

Vue3 中如何封装 API 请求?

  • 基于 axios 或 fetch 封装统一实例。
  • 统一处理 baseURL、token、错误码、超时。
  • 请求函数要有明确入参和返回类型。
  • 不要把 UI 提示和底层请求封装强耦合得太死。

Vue3 中如何处理 token 失效?

  • 响应拦截器识别 401 或业务错误码。
  • 清理用户状态和本地 token。
  • 跳转登录页或刷新 token。
  • 多请求并发刷新 token 时要防止重复刷新。

Vue3 中如何做首屏优化?

  • 路由懒加载,减少首屏 JS。
  • 图片压缩、懒加载、合理尺寸。
  • 第三方库按需加载。
  • SSR/SSG、CDN、缓存、gzip/brotli。

Vue3 中如何做包体积优化?

  • 使用 Vite/Rollup 分析构建产物。
  • 第三方库按需引入。
  • 路由和大组件懒加载。
  • 移除无用依赖,避免重复打包。

Vue3 中如何做表格性能优化?

  • 服务端分页优先。
  • 大数据使用虚拟滚动。
  • 列渲染函数避免复杂计算。
  • 行组件使用稳定 key,避免无意义重渲染。

Vue3 中如何设计一个动态表单?

  • 用 schema 描述字段、组件、校验、联动。
  • 表单状态集中管理,字段组件负责展示和交互。
  • 异步选项、隐藏显示、依赖校验要有清晰规则。
  • schema 不要复杂到难以调试。

Vue3 中如何设计权限按钮?

  • 可以用自定义指令或权限组件。
  • 根据用户权限判断是否渲染或禁用。
  • 前端只是隐藏入口,后端仍要校验接口权限。

Vue3 中如何设计 Tabs 保活?

  • 使用 keep-alive 缓存路由组件。
  • 用 route name 或组件 name 控制 include。
  • 关闭 tab 时清理对应缓存。
  • 注意参数不同但组件相同时的数据刷新。

Vue3 中如何实现面包屑?

  • 可以基于路由 matched 数组生成。
  • 标题通常来自 route.meta.title。
  • 动态详情页标题可能需要接口数据补充。
  • 权限和隐藏路由要特殊处理。

Vue3 中如何实现菜单?

  • 静态菜单可以从路由配置生成。
  • 权限菜单通常由后端返回或前端根据权限过滤。
  • 菜单 key 要和路由 name/path 保持一致。
  • 刷新后要能恢复选中状态。

Vue3 中如何做埋点?

  • 路由切换埋页面访问。
  • 关键按钮和业务流程埋事件。
  • 可以用指令或组件封装点击埋点。
  • 要注意性能、隐私和失败重试策略。

Vue3 中如何做单元测试?

  • 常用 Vitest 和 Vue Test Utils。
  • 测试组件行为,而不是内部实现细节。
  • 对外表现、props、emit、slot、异步状态都可以测试。
  • 组合式函数可以单独测试。

Vue3 中如何做 E2E 测试?

  • 常用 Playwright 或 Cypress。
  • 覆盖登录、权限、表单提交、核心业务链路。
  • E2E 数量不宜过多,优先核心流程。
  • 要保证测试数据和环境稳定。

Vue3 中如何做可访问性?

  • 使用语义化标签。
  • 表单 label 和控件要关联。
  • 弹窗要处理焦点和键盘关闭。
  • 图标按钮要有可读文本或 aria-label。

Vue3 中如何处理 XSS?

  • Vue 默认会转义插值文本。
  • 使用 v-html 时必须确保内容可信或经过净化。
  • URL、富文本、第三方内容都是高风险点。
  • CSP 和后端过滤也很重要。

Vue3 中 v-html 有什么风险?

  • v-html 会直接插入 HTML,可能导致 XSS。
  • 用户输入、第三方内容不能直接 v-html。
  • 需要使用 DOMPurify 等工具净化。

Vue3 中如何处理 CSRF?

  • CSRF 主要依赖后端防护,如 SameSite Cookie、CSRF Token。
  • 前端请求要正确携带 token 或 header。
  • 不要把安全责任只放在前端。

Vue3 中如何处理跨域?

  • 开发环境可以通过 Vite proxy 代理。
  • 生产环境通常由网关或后端配置 CORS。
  • 跨域不是前端单方面能彻底解决的问题。

Vue3 中如何做文件上传?

  • 小文件可以直接 FormData 上传。
  • 大文件考虑分片、断点续传、秒传。
  • 要处理进度、取消、失败重试、类型和大小校验。
  • 服务端仍要做安全校验。

Vue3 中如何做图片懒加载?

  • 可以使用原生 loading="lazy"
  • 也可以用 IntersectionObserver 自定义懒加载。
  • 图片要提供占位、错误图和合理尺寸。

Vue3 中如何实现无限滚动?

  • 监听滚动位置或使用 IntersectionObserver。
  • 到达底部时请求下一页。
  • 要处理 loading、没有更多、错误重试。
  • 大数据仍建议配合虚拟列表。

Vue3 中如何做拖拽排序?

  • 可以使用成熟拖拽库。
  • 数据更新要保持 key 稳定。
  • 拖拽结束后同步排序结果到后端。
  • 注意移动端、可访问性和性能。

Vue3 中如何做低代码渲染?

  • 使用 schema 描述组件、属性、事件、布局。
  • 渲染器根据 schema 动态渲染组件。
  • 要处理组件注册、权限、表达式、安全和版本兼容。
  • 不要让 schema 变成无法维护的第二套编程语言。

Vue3 中如何封装弹窗表单?

  • 外层弹窗控制 open、title、loading。
  • 内层表单控制字段、校验、提交。
  • 提交成功后关闭弹窗并刷新列表。
  • 编辑场景要处理默认值回填和重置。

Vue3 中如何处理组件异步加载失败?

  • defineAsyncComponent 可以配置 loading、error、timeout。
  • 路由懒加载失败要提示刷新或重试。
  • 网络异常和版本发布导致 chunk 失效都要考虑。

defineAsyncComponent 有什么用?

  • 它用于定义异步组件。
  • 可以延迟加载非首屏组件。
  • 支持配置加载态、错误态、延迟和超时。

Vue3 中如何实现全局 Loading?

  • 请求层维护请求计数。
  • 请求开始计数加一,结束计数减一。
  • 计数大于零展示全局 loading。
  • 要处理并发请求和异常结束。

Vue3 中如何避免重复提交?

  • 提交按钮 loading 时禁用。
  • 请求层或业务层加 pending 状态。
  • 后端接口也要保证幂等。
  • 用户快速点击和网络重试都要考虑。

Vue3 中如何做防抖和节流?

  • 防抖适合搜索输入,停止输入后再执行。
  • 节流适合滚动、resize、拖拽等高频事件。
  • 可以封装组合式函数,也可以使用 VueUse。

Vue3 中如何做本地缓存?

  • 少量用户偏好可以放 localStorage。
  • 会话级数据可以放 sessionStorage。
  • 大数据和敏感数据不要随意放本地。
  • 缓存要设计版本和过期策略。

Vue3 中如何处理页面刷新后 Pinia 数据丢失?

  • Pinia 状态默认在内存中,刷新会丢失。
  • 可以在登录后重新拉取用户信息。
  • 也可以持久化部分状态到本地。
  • 敏感信息不要明文长期保存。

Vue3 中如何处理服务端状态?

  • 服务端状态包括接口数据、分页、缓存、刷新、失效。
  • 可以封装请求 Hook 或使用数据缓存库。
  • 不建议全部塞进 Pinia。

Vue3 中如何做乐观更新?

  • 先更新 UI,让用户感觉操作立即成功。
  • 请求成功后确认状态。
  • 请求失败时回滚并提示。
  • 适合点赞、收藏、排序等低风险交互。

Vue3 中如何处理并发请求?

  • 可以用 AbortController 取消旧请求。
  • 也可以给请求加序号,只处理最后一次结果。
  • 批量请求可以使用 Promise.all 或队列控制并发数。

Vue3 中如何封装权限路由?

  • 路由 meta 声明权限。
  • 全局 beforeEach 校验登录态和权限。
  • 无权限跳转 403 或隐藏入口。
  • 动态路由要处理刷新恢复和异步加载。

Vue3 中如何做错误边界?

  • Vue 可以用 onErrorCaptured 捕获子组件错误。
  • 全局可以用 app.config.errorHandler
  • 错误捕获后要记录日志并展示兜底 UI。

onErrorCaptured 有什么用?

  • 捕获后代组件抛出的错误。
  • 返回 false 可以阻止错误继续向上传播。
  • 适合局部错误兜底,但不能替代全局监控。

Vue3 中如何处理异步组件和 Suspense?

  • 异步组件负责延迟加载。
  • Suspense 负责统一展示等待状态。
  • 错误态和超时要单独设计。

Vue3 中如何优化 computed?

  • computed 中不要写副作用。
  • 依赖要尽量明确。
  • 昂贵计算可以拆分或预处理数据。
  • 如果不需要缓存,用普通函数即可。

Vue3 中如何优化 watch?

  • 精确监听具体字段,不要随便 deep 整个对象。
  • 异步请求要处理清理和竞态。
  • 能用 computed 的派生状态不要用 watch。

Vue3 中如何处理深层对象更新?

  • reactive 深层对象默认可以响应式更新。
  • 大对象深层响应式可能有性能成本。
  • 可以使用 shallowReactive、shallowRef 或按模块拆分状态。

Vue3 中如何处理对象属性新增和删除?

  • Vue3 基于 Proxy,可以直接新增或删除属性并触发更新。
  • 不需要 Vue2 的 Vue.setVue.delete
  • 但数据结构仍应尽量稳定,方便维护和类型推导。

Vue3 中如何理解模板自动解包?

  • 模板中顶层 ref 会自动解包。
  • reactive 对象里的 ref 访问也有一定解包规则。
  • JS 逻辑中不要忘记 .value

Vue3 中 reactive 里嵌套 ref 会怎样?

  • reactive 对象属性中的 ref 通常会被自动解包。
  • 数组和集合里的 ref 不会完全按对象属性方式解包。
  • 复杂场景建议保持数据结构简单,避免混用太深。

Vue3 中如何理解 readonly props?

  • 组件接收的 props 是只读的。
  • 子组件不应该直接修改 props。
  • 如果要修改,应该 emit 事件让父组件更新,或用本地副本。

Vue3 中为什么不建议直接修改 props?

  • props 来源在父组件,子组件修改会破坏单向数据流。
  • 父组件重新渲染时可能覆盖子组件修改。
  • 正确方式是 emit 或使用 v-model。

Vue3 中如何实现双向绑定组件?

  • 使用 v-model
  • 子组件接收 modelValue,触发 update:modelValue
  • Vue3.4+ 可以用 defineModel 简化。

Vue3 中如何实现组件递归?

  • 组件需要有 name。
  • 模板中根据数据递归渲染自身。
  • 树组件、菜单、评论嵌套常见。
  • 要注意递归终止条件和性能。

Vue3 中如何实现动态表格列?

  • 用列配置数组驱动渲染。
  • 每列配置 title、field、width、render、权限等。
  • 单元格复杂时使用作用域插槽或 render 函数。
  • 大表格要关注性能和固定列。

Vue3 中 render 函数适合什么场景?

  • 适合高度动态 UI、组件库底层、低代码渲染。
  • 普通业务页面模板更直观。
  • render 函数需要更强的 JS 和 vnode 理解。

Vue3 支持 JSX 吗?

  • 支持,但需要对应插件和配置。
  • JSX 适合动态逻辑复杂的组件。
  • 大多数 Vue 项目仍以 SFC 模板为主。

Vue3 中如何处理样式隔离?

  • scoped CSS 可以做组件级隔离。
  • CSS Modules 也能避免类名污染。
  • 组件库通常配合命名规范和 CSS 变量。

Vue3 中如何设计可复用页面?

  • 抽离业务 Hook 管理数据和动作。
  • 抽离展示组件负责 UI。
  • 抽离配置描述表格、表单、筛选项。
  • 不要为了复用牺牲可读性。

Vue3 中如何设计后台管理系统架构?

  • 路由、权限、菜单、布局、请求、状态管理要先定好。
  • 业务模块按领域拆分。
  • 通用组件、业务组件、页面组件分层。
  • 规范比炫技更重要。

Vue3 中如何处理多标签页缓存?

  • 路由 meta 标记缓存策略。
  • keep-alive 缓存页面组件。
  • Pinia 维护打开的 tab 列表。
  • 关闭 tab 时同步清理缓存和状态。

Vue3 中如何做微前端集成?

  • 可以使用 qiankun、micro-app、Module Federation 等方案。
  • 要处理路由隔离、样式隔离、状态通信、依赖冲突。
  • 适合多团队独立发布的大型系统。

Vue3 中如何做组件按需加载?

  • 业务组件可以使用动态 import。
  • UI 组件库可以使用自动导入插件。
  • 注意按需加载后的样式引入和 Tree-shaking。

Vue3 中如何使用 unplugin-auto-import?

  • 可以自动导入 Vue、Vue Router、Pinia 等 API。
  • 减少重复 import。
  • 团队要统一配置,避免新人不知道 API 来源。

Vue3 中如何使用 unplugin-vue-components?

  • 可以自动导入组件。
  • 常用于自动导入 Element Plus、Vant、自定义组件。
  • 要注意组件命名规范和构建配置。

Element Plus 在 Vue3 项目中如何按需引入?

  • 可以配合自动导入插件。
  • 只引入实际使用的组件和样式。
  • 还要关注主题变量、自定义样式和国际化配置。

Vant 在 Vue3 移动端项目中要注意什么?

  • 注意适配方案,如 viewport、rem、safe-area。
  • 组件按需引入减少包体积。
  • 移动端要关注触摸体验、键盘遮挡和性能。

Vue3 中如何做移动端适配?

  • 可以使用 rem、vw、响应式布局。
  • 注意 iPhone safe-area。
  • 图片和字体尺寸要适配高清屏。
  • 输入框和键盘交互要重点测试。

Vue3 中如何处理滚动恢复?

  • Vue Router 支持 scrollBehavior。
  • keep-alive 页面可以在 activated 中恢复滚动。
  • 列表页进入详情再返回是高频场景。

Vue3 中如何处理页面标题?

  • 可以在路由 meta 中配置 title。
  • 全局 afterEach 中设置 document.title。
  • 动态标题可以在页面获取数据后更新。

Vue3 中如何处理面包屑动态标题?

  • 静态标题从 route.matched 的 meta 获取。
  • 动态详情页可在接口返回后更新标题。
  • 复杂系统可以维护一个标题映射或页面状态。

Vue3 中如何处理菜单高亮?

  • 根据当前 route.path 或 route.name 计算 active key。
  • 父级菜单要根据 matched 展开。
  • 动态路由和重定向要保持 key 一致。

Vue3 中如何处理 404 页面?

  • 静态路由中配置 catch-all 路由。
  • 动态路由场景要在权限路由添加完成后再处理 404。
  • 否则刷新动态页面可能误进 404。

Vue3 中如何处理 403 页面?

  • 用户已登录但无权限访问时跳转 403。
  • 和未登录跳转登录页要区分。
  • 后端接口也应返回明确权限错误。

Vue3 中如何设计登录流程?

  • 登录接口返回 token 或 session。
  • 保存用户信息和权限。
  • 拉取菜单或动态路由。
  • 跳转原目标页面或首页。

Vue3 中如何处理刷新丢路由?

  • 刷新后 Pinia 内存状态清空。
  • 需要根据 token 重新拉取用户信息和路由。
  • 动态路由添加完成后再放行当前导航。

Vue3 中如何处理 axios 拦截器?

  • 请求拦截器添加 token、trace id、公共参数。
  • 响应拦截器统一处理错误码和数据解包。
  • 不同业务错误要给调用方保留处理空间。

Vue3 中如何取消请求?

  • fetch 可以用 AbortController。
  • axios 新版本也支持 AbortController。
  • 页面切换、参数变化、重复搜索时常用。

Vue3 中如何处理请求 loading?

  • 局部 loading 放在页面或组件状态中。
  • 全局 loading 可由请求计数管理。
  • 表格、按钮、弹窗 loading 要区分,避免体验混乱。

Vue3 中如何处理接口错误提示?

  • 通用错误在拦截器统一提示。
  • 表单字段错误回显到具体字段。
  • 特殊业务错误交给页面处理。
  • 不要所有错误都弹同一个 toast。

Vue3 中如何处理空状态?

  • 列表无数据、搜索无结果、权限为空要区分。
  • 空状态文案要说明原因和下一步动作。
  • 不要只显示一片空白。

Vue3 中如何处理骨架屏?

  • 首屏卡片、列表、详情页可以使用骨架屏。
  • 骨架屏应该接近真实布局。
  • 过度使用会增加维护成本。

Vue3 中如何处理主题色动态切换?

  • 基于 CSS 变量维护颜色 token。
  • 切换主题时修改根节点 class 或变量。
  • 组件库主题要同步修改变量或使用官方主题机制。

Vue3 中如何处理暗色模式?

  • 可以使用 CSS 变量和 prefers-color-scheme
  • 用户手动选择要覆盖系统设置。
  • 选择结果可以持久化。

Vue3 中如何处理图表组件?

  • 图表实例通常用 shallowRef 或 markRaw 保存。
  • mounted 初始化,unmounted 销毁。
  • 数据变化时调用 setOption,而不是反复重建实例。
  • resize 要节流。

Vue3 中如何处理地图组件?

  • 地图实例不建议深层响应式代理。
  • 使用 markRaw 保存实例。
  • 清理覆盖物、事件监听和地图实例。
  • 注意异步加载 SDK 的失败处理。

Vue3 中如何处理富文本编辑器?

  • 编辑器实例用 shallowRef 或 markRaw。
  • 初始化和销毁要和生命周期绑定。
  • 内容同步要避免频繁触发父组件更新。
  • 粘贴 HTML 要做安全过滤。

Vue3 中如何处理 WebSocket?

  • 连接建立放在组合式函数或 store 中。
  • 组件卸载时关闭或取消订阅。
  • 要处理重连、心跳、鉴权、消息队列。
  • 页面级连接和全局连接要区分。

Vue3 中如何处理轮询?

  • 使用定时器或请求库轮询能力。
  • 页面不可见、组件卸载、路由离开时暂停。
  • 失败重试要有上限。
  • 高频轮询要评估后端压力。

Vue3 中如何做 Web Worker?

  • 适合大计算、文件解析、数据处理。
  • Worker 不能直接访问 DOM。
  • 和主线程通过 postMessage 通信。
  • Vite 支持较方便的 Worker 引入方式。

Vue3 中如何处理大量表单字段?

  • 字段状态可以按模块拆分。
  • 校验按需触发,不要每次输入都全量校验。
  • 大表单可以分步、分组、虚拟化。
  • 表单 schema 要保持可维护。

Vue3 中如何处理动态组件类型?

  • 使用组件映射表,不要直接执行不可信字符串。
  • schema 中存组件 key,运行时映射到真实组件。
  • 未知组件要有兜底。

Vue3 中如何做页面级状态隔离?

  • 页面内部状态优先放组件本地。
  • 多页面共享再放 Pinia。
  • 离开页面需要清理的状态要有 reset。
  • keep-alive 页面要额外处理缓存状态。

Vue3 中如何处理组件 emit 命名?

  • 事件名要表达发生了什么,而不是父组件要做什么。
  • v-model 更新事件使用 update:xxx
  • 组件库事件要稳定,避免频繁破坏兼容。

Vue3 中如何处理 props 默认值?

  • 运行时声明可以写 default。
  • 类型声明可以配合 withDefaults。
  • Vue3.5+ props 解构可以使用 JS 默认值。
  • 对象和数组默认值要避免共享引用。

Vue3 中如何处理 emits 类型?

  • TypeScript 中可以用函数重载或对象形式声明。
  • 明确事件参数类型能减少误用。
  • 组件库尤其需要严格声明。

Vue3 中如何处理 slot 类型?

  • <script setup> 中可以用 defineSlots 声明。
  • 插槽参数会获得类型提示。
  • 适合表格、列表、布局等高复用组件。

Vue3 中如何处理组件 name?

  • 组件 name 用于 Devtools、keep-alive include、递归组件。
  • <script setup> 可通过文件名推断,也可用 defineOptions 显式声明。
  • 组件库建议显式规范命名。

Vue3 中如何处理异步 setup?

  • setup 可以返回 Promise,但通常需要 Suspense 配合。
  • 普通页面请求不一定要写成异步 setup。
  • SSR 中异步 setup 更常见。

Vue3 中如何处理模板中的复杂逻辑?

  • 复杂表达式应抽到 computed 或方法中。
  • 模板应主要描述结构。
  • 过多逻辑会降低可读性和可维护性。

Vue3 中 methods、computed、watch 怎么选?

  • 事件行为用 methods。
  • 派生数据用 computed。
  • 数据变化后执行副作用用 watch。
  • 不要用 watch 做所有事情。

Vue3 中如何处理组件刷新?

  • 状态变化会自动触发更新。
  • 想重置组件可以改变 key。
  • 不建议依赖强制刷新,通常说明状态设计有问题。

Vue3 中如何处理页面缓存失效?

  • keep-alive 页面可以在 activated 中判断是否刷新。
  • 路由 meta 或 store 中记录缓存版本。
  • 关闭 tab、权限变化、参数变化时清理缓存。

Vue3 中如何做项目规范?

  • 统一 ESLint、Prettier、TypeScript、提交规范。
  • 统一目录、命名、组件 API 设计。
  • 关键逻辑要有测试和文档。
  • 规范要能落地,不要只停在文档。

Vue3 中如何做代码评审?

  • 看组件职责是否清晰。
  • 看响应式和副作用是否合理。
  • 看边界状态、错误处理、性能和类型。
  • 看是否破坏现有 API 或用户体验。

Vue3 中如何回答性能优化面试题?

  • 先说定位工具:Vue Devtools、Performance、Network、构建分析。
  • 再说渲染优化:v-memo、v-once、computed、组件拆分、大列表虚拟滚动。
  • 再说资源优化:懒加载、按需引入、图片优化、CDN、缓存。
  • 最后强调不要盲目优化,要用数据验证。

Vue3 中如何回答响应式原理面试题?

  • 先说 Proxy 代理对象。
  • 读取时 track 收集依赖,修改时 trigger 派发更新。
  • 组件渲染、computed、watch 都依赖响应式系统。
  • 再补充 ref、reactive、解构丢失响应式等细节。

Vue3 中如何回答 Composition API 面试题?

  • 先说它按逻辑组织代码,提升复用和维护性。
  • 再对比 Options API 中逻辑分散的问题。
  • 结合自定义 Hook、TypeScript、复杂组件说明价值。

Vue3 中如何回答 Pinia 面试题?

  • 先说 Pinia 是 Vue 官方推荐状态管理。
  • 说明 state、getters、actions。
  • 对比 Vuex:无 mutations、类型更友好、模块化更自然。
  • 补充 storeToRefs 解构响应式问题。

Vue3 中如何回答 Vue Router 面试题?

  • 说清 hash/history、路由守卫、懒加载、动态路由。
  • Composition API 中使用 useRouter/useRoute。
  • 权限系统要结合 meta、动态路由、后端权限。

Vue3 中如何回答 Vite 面试题?

  • 开发环境基于原生 ESM,按需编译。
  • 依赖预构建提升启动和加载速度。
  • 生产构建基于 Rollup。
  • 环境变量必须以 VITE_ 暴露给客户端。

Vue3 中如何回答 SSR 面试题?

  • SSR 是服务端生成 HTML,有利于首屏和 SEO。
  • 客户端需要 hydration 接管交互。
  • 要注意 hydration mismatch、服务端压力和浏览器 API 兼容。

Vue3 中如何回答 Vue3.4 新特性?

  • Vue3.4 稳定了 defineModel
  • 支持 v-bind 同名简写。
  • computed 支持获取 previous value。
  • 模板解析器和响应式系统也有性能优化。

Vue3 中如何回答 Vue3.5 新特性?

  • 响应式 props 解构默认启用。
  • 新增 useTemplateRef
  • watch deep 支持数字深度。
  • 新增 onWatcherCleanup 等 watcher 清理能力。

Vue3 中如何讲自己的项目实践?

  • 不要只背 API,要结合真实项目。
  • 例如权限路由、动态菜单、表格性能、表单封装、Pinia 状态拆分。
  • 说明遇到的问题、方案选择和最终收益。
  • 能讲清权衡,比堆技术名词更重要。

参考资料