Skip to content

Vue 高频面试题 50 道

这里汇总了 50 道 Vue.js 开发岗位常问的面试题,涵盖 Vue 2、Vue 3、原理及生态系统。

一、Vue 基础 (1-10)

  1. Vue 的核心特性是什么?
    • 数据驱动 (MVVM):自动将数据渲染到视图。
    • 组件化:提高复用性和可维护性。
    • 指令系统v-if, v-for, v-model 等。
  2. v-showv-if 的区别?
    • v-if 是真正的条件渲染,条件为假时不渲染 DOM(销毁/重建)。适合不常切换的场景。
    • v-show 始终渲染 DOM,通过 CSS display: none 控制显隐。适合频繁切换的场景。
  3. v-forkey 的作用是什么?
    • key 是虚拟 DOM 节点的唯一标识。Vue 的 Diff 算法通过 key 判断新旧节点是否是同一个,从而复用节点,提高渲染性能。
    • 注意:避免使用 index 作为 key,这会在列表顺序变化时导致状态错乱。
  4. Vue 的生命周期有哪些(Vue 2 vs Vue 3)?
    • Vue 2: beforeCreate, created (数据可用), beforeMount, mounted (DOM可用), beforeUpdate, updated, beforeDestroy, destroyed.
    • Vue 3: 大部分对应,但 Destroy 改为 beforeUnmount, unmounted. 组合式 API 中使用 onMounted 等。
  5. Vue 组件间通信有哪些方式?
    • 父子: props / $emit, $parent / $children, ref.
    • 跨级: provide / inject, $attrs / $listeners.
    • 兄弟/任意: EventBus (Vue 2), Vuex / Pinia, Mitt (Vue 3).
  6. computedwatch 的区别?
    • computed: 计算属性,依赖其他属性计算值,有缓存(依赖不变不重新计算),不支持异步。
    • watch: 监听属性,数据变化时执行回调,支持异步和开销大的操作,无缓存。
  7. v-model 的原理是什么?
    • 本质是语法糖。
    • input 元素上::value="data" @input="data = $event.target.value"
    • 在组件上:Vue 2 是 :value + @input (或 model 选项配置);Vue 3 是 :modelValue + @update:modelValue
  8. nextTick 是什么?有什么用?
    • Vue 的 DOM 更新是异步的。nextTick 接受一个回调,在下一次 DOM 更新循环结束之后执行。
    • 用途:修改数据后,立即获取更新后的 DOM。
  9. 为什么 data 在组件中必须是一个函数?
    • 为了保证每个组件实例维护一份独立的 data 副本。如果 data 是对象,所有实例将共享同一个数据对象(引用)。
  10. Vue 如何检测数组变化?
    • Vue 2 拦截了数组的 7 个变异方法 (push, pop, shift, unshift, splice, sort, reverse) 来触发更新。直接修改索引 (arr[0]=1) 无法检测。
    • Vue 3 使用 Proxy,可以直接检测数组索引和长度变化。

二、Vue 3 新特性 (11-20)

  1. Vue 2 和 Vue 3 的主要区别?
    • 响应式原理: Vue 2 (Object.defineProperty) vs Vue 3 (Proxy).
    • API 风格: Options API vs Composition API.
    • 性能: Vue 3 更快,体积更小,Tree-shaking 支持更好。
    • 新组件: Fragment, Teleport, Suspense.
  2. Composition API (组合式 API) 的优势?
    • 更好的逻辑复用 (Composables)。
    • 代码按业务逻辑组织,而非按选项 (data/methods) 分割,利于维护大型组件。
    • 更好的 TypeScript 类型推导。
  3. Object.definePropertyProxy 的区别?
    • defineProperty: 只能劫持对象的属性,需要遍历;无法监听新增/删除属性;无法监听数组下标。
    • Proxy: 劫持整个对象;支持数组;性能更好;懒代理(嵌套对象深层)需手动处理。
  4. Vue 3 中的 refreactive 有什么区别?
    • ref: 用于基本数据类型(也可以包对象),通过 .value 访问。
    • reactive: 用于对象/数组,基于 Proxy,直接访问属性,不能解构(会丢失响应性,需用 toRefs)。
  5. 什么是 Teleport?
    • 将组件内部的 DOM 渲染到当前组件树之外的节点(如 body),常用于 Modal、Toast。
  6. Vue 3 的生命周期钩子有何变化?
    • beforeCreate / created -> setup()
    • mounted -> onMounted
    • destroyed -> onUnmounted
  7. <script setup> 是什么?
    • Composition API 的语法糖。代码更简洁,顶层变量直接在模板可用,无需 return
  8. Vue 3 如何实现 Tree-shaking?
    • 大部分全局 API (如 nextTick, defineComponent) 改为具名导出,未使用的功能在打包时会被移除。
  9. WatchEffect 和 Watch 的区别?
    • watchEffect: 自动收集依赖,立即执行一次。
    • watch: 需显式指定数据源,默认只有变化时执行(除非 immediate: true)。
  10. Vue 3 为什么支持 Fragment(多根节点)?
    • Vue 3 的渲染引擎通过虚拟 DOM 的打平,不再强制要求组件必须有一个根节点,减少了无意义的 wrapper div。

三、Vue 原理 (21-30)

  1. 简述 Vue 的响应式原理 (Vue 2)。
    • Observer: 遍历 data,用 Object.defineProperty 将属性转为 getter/setter。
    • Dep: 依赖收集器,属性 getter 时收集 Watcher,setter 时通知 Watcher。
    • Watcher: 订阅者,收到通知后执行回调更新视图。
  2. 简述 Vue 的 Diff 算法 (双端 Diff)。
    • 同层比较,不跨级。
    • Vue 2 采用双端比较:新旧列表的 头头、尾尾、头尾、尾头 依次尝试对比,若都没中则查 Map。
    • Vue 3 采用最长递增子序列算法来优化乱序移动的情况。
  3. 虚拟 DOM (Virtual DOM) 真的比真实 DOM 快吗?
    • 不一定。首次渲染由于要创建 VDOM,比直接 innerHTML 慢。
    • 优势在于更新阶段,通过 Diff 算法减少了不必要的真实 DOM 操作,且具备跨平台能力。
  4. Vue 模板编译 (Template Compilation) 的过程?
    • Template -> AST (抽象语法树) -> Optimize (标记静态节点) -> Generate (生成 render 函数字符串)。
  5. keep-alive 的原理是什么?
    • LRU (Least Recently Used) 缓存策略。
    • 在组件切换时,不销毁组件实例,而是将其缓存到内存中。再次激活时触发 activated 钩子。
  6. Vue 是如何处理 Slot 的?
    • 普通插槽:在父组件编译,当作子组件的 props 传入。
    • 作用域插槽:父组件传一个函数给子组件,子组件调用函数并传参。
  7. $nextTick 的实现原理?
    • 利用 JS 事件循环微任务/宏任务。优先使用 Promise.then (微任务),降级依次为 MutationObserver, setImmediate, setTimeout
  8. 为什么 Vue 2 中给对象添加新属性是非响应式的?
    • 初始化时 defineProperty 已经执行完毕。解决:Vue.set(obj, key, val)
  9. Vue 组件中的 data 为什么要是函数?
    • 防止多个组件实例共享同一个数据对象(闭包特性)。
  10. 什么是 render 函数?
    • 模板最终都会被编译成 render 函数,它返回 VNode。可以直接手写 render 函数(配合 JSX)来获得更高的灵活性。

四、Vue 全家桶 (Router & Vuex/Pinia) (31-40)

  1. Vue-Router 的两种模式及原理?
    • Hash: URL 带 #,利用 window.onhashchange 监听。兼容性好。
    • History: URL 无 #,利用 HTML5 History API (pushState, replaceState) 和 popstate 事件。需后端配置支持。
  2. Vue-Router 导航守卫有哪些?
    • 全局: beforeEach, beforeResolve, afterEach.
    • 路由独享: beforeEnter.
    • 组件内: beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave.
  3. Vuex 有哪几种属性?
    • State (数据), Getters (计算属性), Mutations (同步修改), Actions (异步操作), Modules (模块化)。
  4. Vuex 中 Mutation 和 Action 的区别?
    • Mutation 必须是同步的,用于修改 State (DevTools 追踪)。
    • Action 可以包含异步操作,通过 commit 提交 Mutation。
  5. Pinia 相比 Vuex 有什么优势?
    • API 更简单(去掉了 Mutation,只有 State, Getters, Actions)。
    • 原生支持 TypeScript。
    • 体积更小,模块化更自然(不需要嵌套 module)。
  6. Vue-Router 中 $route$router 的区别?
    • $route: 当前路由信息对象 (path, params, query)。
    • $router: 路由实例,包含跳转方法 (push, replace, go)。
  7. 如何实现路由懒加载?
    • component: () => import('./MyComponent.vue') (Webpack 代码分割)。
  8. Vuex 是如何实现响应式的?
    • Vuex 3 本质上是创建了一个 Vue 实例,将 state 存放在该实例的 data 中。
  9. history 模式下刷新页面 404 怎么办?
    • 后端(Nginx/Apache)需配置:如果 URL 匹配不到静态资源,统一返回 index.html
  10. Pinia 可以在组件外使用吗?
    • 可以,只要在 createPinia() 安装之后即可使用。

五、进阶与优化 (41-50)

  1. Vue 项目性能优化的常见手段?
    • 路由懒加载。
    • keep-alive 缓存组件。
    • v-show 复用 DOM。
    • v-for 使用正确 key,避免同时使用 v-if
    • 长列表虚拟滚动 (vue-virtual-scroller)。
    • 图片懒加载 (v-lazy)。
    • Object.freeze (Vue 2) 冻结不需要响应式的大数据。
  2. SPA (单页应用) 的首屏加载慢怎么解决?
    • 代码分割 (SplitChunks)、路由懒加载。
    • CDN 引入第三方库。
    • Gzip 压缩。
    • SSR (Nuxt.js) 或 预渲染。
  3. Vue 3 的 hoistStatic (静态提升) 是什么?
    • 编译器优化。将静态节点/属性提升到 render 函数之外,只创建一次,后续更新直接复用,不参与 Diff。
  4. 什么是 SSR?Vue 如何实现 SSR?
    • 服务端渲染。使用 vue-server-renderer (Vue 2) 或 Vue 3 的 SSR API,通常配合 Nuxt.js 框架。
  5. 自定义指令 (Directive) 的钩子?
    • Vue 2: bind, inserted, update, componentUpdated, unbind.
    • Vue 3: created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted.
  6. 如何解决 Vue 中的跨域问题?
    • 开发环境:配置 vue.config.js / vite.config.js 中的 proxy (代理)。
    • 生产环境:Nginx 反向代理或后端 CORS。
  7. assets 和 static (public) 目录的区别?
    • assets: 会被 Webpack/Vite 编译处理(压缩、Hash、Base64)。
    • static/public: 不经过编译,直接拷贝到根目录。
  8. Vue 错误处理 (Error Handling)?
    • errorCaptured 钩子 (组件内)。
    • app.config.errorHandler (全局)。
  9. Vue 3 中的 defineAsyncComponent 是什么?
    • 用于定义异步组件,支持加载状态、错误组件、超时设置等。
  10. 说一下 Vue 的 EventBus?
    • Vue 2 中常用 new Vue() 作为中央事件总线。Vue 3 移除了 $on, $off, $emit 实例方法,推荐使用 external 库 (如 mitt) 或全局状态管理。

MIT Licensed | Keep Learning.