Vue 常见面试题

287 阅读8分钟

页面渲染优化

  1. 从回流的角度:html 不要嵌套过深,减轻回流的压力
  2. css 尽量使用精确的选择器(id和类名)减轻回流的压力
  3. 代码压缩(减轻请求的压力)
  4. js 线程不能和渲染线程同时工作,async 异步加载,defer 异步加载且延迟加载
  5. js 代码压缩
  6. 图片(懒加载,预加载,骨架屏,压缩,精灵图)
  7. 缓存

谈谈你对 vue 的理解

  1. vue 是一个渐进式的单页应用框架(页面上只有一个html文件,靠组件和路由来切页面,在开发时需要什么就开发什么)
  2. MVVM 数据驱动(model view viewModel):以数据来驱动页面更新,只要写模板代码,不需要去操作dom
  3. 组件化:提高代码的复用性,便于维护
  4. 便于开发的指令
  5. 虚拟 dom :跨端开发,减少 dom 操作
  6. 生态系统丰富(路由,仓库,第三方框架)

谈谈你对spa的理解

  1. 整个项目只有一个页面
  2. 页面中的内容是动态的,以组件的形式展示,靠路由来映射匹配组件

优点:

  1. 组件化开发,易于维护
  2. 页面切换快,体验好
  3. 前后端分离,提高开发效率
  4. 减轻服务器压力,提高性能

缺点:

  1. 初次加载慢
  2. 不利于SEO(可以使用 SSR)

说说你的 vue 生命周期的理解

vue 组件从创建到销毁的过程,其中官方提供了一系列的钩子函数

左部分是 Vue3,右边是 Vue2

  1. setup == beforeCreate + created
  2. onBeforeMount == beforeMount
  3. onMounted == mounted
  4. onBeforeUpdate == beforeUpdate
  5. onUpdated == updated
  6. onBeforeUnmount == beforeUnmount
  7. onUnmounted == unmounted
  8. onActivated == activated
  9. onDeactivated == deactivated

如果想要了解更多的话,可以看 Vue 的官网:cn.vuejs.org/api/ 响应式api也可以了解一下

说说你对双向绑定的理解

- 是什么: v-model = v-on + v-bind

修改数据,页面同步更新,页面内容修改,数据也会同步更新

- 原理: model view viewModel

- ViewModel: 1. Observer 监听器 2. Compile 解析器

(这个会有点复杂,后面出一篇文章来讲解)

- 双向绑定的原理:

  1. 单向绑定:变量被处理成响应式的过程中会为变量做依赖收集,当变量的值变更时,触发 setter ,并执行依赖,导致视图更新
  2. 双向绑定:视图更新用等同于用户触发了 input 函数,修改响应式变量,进而又导致 setter 触发

vue 的组件通信

我这里有一篇文章写的比较详细:juejin.cn/post/748898…

通信方式实现形式数据流向适用场景优点缺点
Props 传值v-bind + defineProps父→子父子数据传递类型安全/单向数据流多层传递繁琐
v-model 双向绑定v-model:prop 语法糖父子双向表单组件/双向绑定简化代码/标准语法需严格定义 update 事件
自定义事件defineEmits + v-on子→父子组件通知父组件显式数据流需维护事件名
组件实例暴露defineExpose + ref父访问子调用子组件方法/状态灵活破坏封装性
Provide/Injectprovide + inject祖先→后代跨层级共享避免逐层传递数据流向不透明
共享状态对象响应式对象模块化任意组件简单兄弟通信实现简单难以维护
Pinia 状态库defineStore + useStore全局复杂应用状态管理调试工具支持需学习额外 API

watch 和 computed 的区别

特性computedwatch
设计目的派生新数据(基于其他数据计算得到结果)监听数据变化并执行副作用(如异步操作、DOM 操作)
是否有返回值✅ 必须有返回值❌ 无返回值
缓存机制✅ 依赖不变时直接返回缓存结果❌ 每次数据变化都触发回调
依赖追踪自动追踪函数内所有响应式依赖需手动指定监听的目标数据
适用场景模板中简化复杂逻辑、需要缓存结果的计算(如格式化数据、过滤列表)异步任务(如接口请求)、监听变化执行操作(如日志记录)、需要旧值和新值对比
性能优化高效(减少重复计算)需谨慎使用(避免高频监听导致性能问题)
是否支持异步❌ 计算函数必须是同步的✅ 可在回调中执行异步操作
语法(Options API)在 computed 选项中定义函数在 watch 选项中定义对象或函数
初始化是否触发✅ 默认立即计算并缓存结果❌ 默认不触发(需设置 immediate: true

v-if 和 v-show 的区别

1. 控制手段: v-if 为 false 时,不加载 dom 树, v-show = false,是用 display=none

2. 编译不同: v-if 控制的组件会触发生命周期(有重新编译和卸载的过程),而 v-show 不会

3. 性能: v-if 有更高的切换开销

v-if 可以和 v-for 一起使用吗

- vue3: 可以,但不推荐,v-if 的优先级比 v-for 高

- vue2 : 不行,v-for 的优先级比 v-if 高

SPA 首屏加载优化

- 首屏加载慢原因

  1. 单页应用需要把所有的页面代码都执行完毕,首屏才会加载
  2. 需要加载 js 脚本
  3. 网络延时

- 优化方法

  1. 路由懒加载
  2. SSR 服务端渲染
  3. 骨架屏
  4. UI 框架按需加载

为什么 vue 支持双向绑定,但是数据流是单向的

Vue 的单向数据流通过 props 向下传递、事件向上通信 的机制,平衡了灵活性与可控性。尽管提供了 v-model 等便捷语法,底层仍严格遵循单向原则,确保数据变化的可预测性和可维护性。这种设计尤其适合复杂应用的长期迭代。

  • 可维护性:组件关系清晰,数据变更路径明确(适合大型项目)。
  • 调试友好,来源明确:通过 Vue Devtools 可直接追踪数据变化来源。
  • 避免副作用:子组件无法意外污染父组件状态(如直接修改对象属性)。

为什么 data 要是一个函数

  • 如果 data 是一个对象,那么当组件被多次复用时,会导致数据共享,会出现数据污染的问题。因为 data 必须是一个函数,返回一个对象,每个组件的实例都有一个自己的对象

说说你对 vue 中的 nextTick 的理解

是什么: vue 官方给我们提供的异步函数,作用是在 dom 更新完成之后执行延迟回调

应用场景: 当我们需要 dom 更新之后的数据

原理: 在拥有 MutationObserver 的环境中,使用 MutationObserver监听,在 dom 更新后触发回调,是微任务在不支持 MutationObserver 的环境中,使用 setTimeOut 来触发回调,是宏任务

vue2 和 vue3 了解吗,有什么区别?

  1. 静态缓存
  • 静态提升(Hoist Static) :将模板中的静态节点(无动态绑定的元素)提升到渲染函数外部,复用同一个虚拟 DOM 节点,减少重渲染开销。

  • 示例

    <!-- 模板 -->
    <div>
      <h1>Static Title</h1>  <!-- 静态节点,会被缓存 -->
      <p>{{ dynamicText }}</p>
    </div>
    
  1. diff 算法
  • Vue2(Object.defineProperty)

    • 递归遍历对象属性,通过 getter/setter 拦截数据变化。
    • 缺点:无法检测对象新增/删除属性(需用 Vue.set/Vue.delete),对数组需重写方法(如 push)。
  • Vue3(Proxy)

    • 使用 Proxy 代理整个对象,直接监听对象/数组的变化。

    • 优势

      • 支持动态新增/删除属性。
      • 原生支持数组索引修改和 length 变化。
      • 性能更高,惰性响应(按需触发更新)。
  1. v-if 和 v-for 的优先级
  • Vue2v-for 优先级高于 v-if,导致循环所有元素后再条件过滤,性能浪费。
  • Vue3v-if 优先级高于 v-for,避免不必要的循环。
  1. 生命周期
  • Vue2beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestroydestroyed

  • Vue3

    • 移除 beforeCreate 和 created,用 setup 替代。

    • 其他钩子改名(更语义化):

      • beforeDestroy → onBeforeUnmount
      • destroyed → onUnmounted
  1. 组合式 api
  • Vue2(Options API) :逻辑分散在 datamethodscomputed 等选项中,大型组件难以维护。

  • Vue3(Composition API)

    • 使用 setup 函数集中管理逻辑,通过函数组合实现高复用性。
  1. 响应式原理
  • Vue2(Object.defineProperty)

    • 递归遍历对象属性,通过 getter/setter 拦截数据变化。
    • 缺点:无法检测对象新增/删除属性(需用 Vue.set/Vue.delete),对数组需重写方法(如 push)。
  • Vue3(Proxy)

    • 使用 Proxy 代理整个对象,直接监听对象/数组的变化。

    • 优势

      • 支持动态新增/删除属性。
      • 原生支持数组索引修改和 length 变化。
      • 性能更高,惰性响应(按需触发更新)。
  1. 更好的TS支持
  • Vue3 源码用 TS 重写,提供更好的类型推导。
  1. 性能
  • Vue3 打包体积更小(Tree-shaking 优化),运行速度更快。

题外话

欢迎在评论区留下你的最难Vue面试题,互助答疑!