Vue3 与 TypeScript 高频面试题梳理
初探与基础概念
谈谈对 Vue 的理解及版本演进
Vue 是一个渐进式 JavaScript 框架。发展历程如下:
- 2013 年诞生
- 2016 年发布 2.0 版本
- 2019 年发布 2.6 版本
- 2020 年 9 月发布 3.0(代号海贼王)
- 2021 年 8 月支持
<script setup>语法糖
Vue 3 值得关注的新特性:
- 组合式 API (Composition API):相比选项式 API,更贴近原生 JS 逻辑,方便逻辑复用和封装。
- 单文件组件中的组合式 API 语法糖 (
<script setup>):在setup函数中直接写变量,无需返回,代码更简洁。 - Teleport 组件:将组件内部的一部分模板'传送'到 DOM 结构外层的位置,常用于模态框等场景。
- Fragments 片段:正式支持多根节点的组件,不再需要包裹一个父元素。
- Emits 组件选项:用于声明由组件触发的自定义事件,
.native修饰符已移除。 - Suspense:实验性组件,用于处理异步依赖。
- 状态驱动的 CSS 变量:在
<style>中使用v-bind。
Vue 常用指令速查
- {{ }}:大括号内是 JS 环境,支持三元表达式、拼接等。
- v-text / v-html:覆盖元素内容,注意 XSS 风险。
- v-cloak / v-pre / v-once:开发中较少使用,主要用于优化首屏或跳过编译。
- v-bind (: ):绑定属性数据,减少 DOM 操作。简写为冒号。
- v-on (@ ):事件监听。推荐函数名以
on开头,在 methods 中定义。支持事件修饰符(stop, prevent, 键盘/系统修饰符)。 - v-for:遍历数组、对象或数字。
key的作用至关重要,底层 Diff 算法根据 key 决定替换、修改或删除节点,避免 Bug 并提升性能。优先级上,Vue 3 中v-if总是优先于v-for。 - v-if / v-show:
v-if:真正的条件渲染,惰性执行,切换时销毁重建组件和事件监听器。适用于不频繁切换的场景。v-show:始终渲染,仅通过 CSSdisplay切换。适用于高频切换场景(如 Tab 切换、弹窗),减少 DOM 操作开销。
- v-memo:类似 React 的 memo,用于缓存特定块,避免重复渲染。
Vue 2 与 Vue 3 的核心区别
从框架设计思想看,Vue 3 更贴近原生 JS,去除了抽象层(如过滤器、混入),引入 Hooks 思想(组合式 API)。
- 响应式原理:Vue 2 使用
Object.defineProperty,无法监听对象新增属性;Vue 3 使用Proxy,可拦截整个对象,支持未定义属性,且性能更强。 - 构建工具:Webpack 改为 Vite,启动速度显著提升。
- 状态管理:Vuex 改为 Pinia,去掉了 mutations,直接使用 Composition API。
- 生命周期:
destroyed改为unmounted,新增onRenderTracked等调试钩子。
MVVM 与 MVC 模式
- MVC:Model-View-Controller。后端常见,单向通信,V 和 M 耦合度较高。
- MVVM:Model-View-ViewModel。前端主流,双向绑定。ViewModel 作为桥梁,自动同步数据变化,减少了大量手动 DOM 操作。
注:Vue 并非纯 MVVM 框架,但受其启发,文档中常用
vm表示实例。
选项式 API 详解
Class 与 Style 绑定
- 目的:利用模型数据动态控制样式,减少 DOM 操作。
- 语法:
:class="dataKey":class="{ className: boolean }":class="[array]":style="{ cssProp: value }"
- 场景:Tab 切换、菜单高亮、文章字体调整。
自定义指令
- 作用:封装 DOM 操作,提高复用性。
- 场景:全屏、拖拽、水印、登录按钮鉴权。
双向绑定 v-model 原理
本质是 :value 和 @input 的语法糖。在 Vue 3 组件中,默认 prop 名为 modelValue,事件名为 update:modelValue。
响应式原理对比
- Vue 2:
Object.defineProperty劫持属性。存在失效场景(对象新增属性、数组索引修改),需配合$set或$forceUpdate。 - Vue 3:
Proxy代理整个对象。支持监听未定义属性,深度嵌套自动代理,性能更优。
计算属性与侦听器
- 计算属性 (computed):有缓存机制,依赖项不变则不重新计算。适用于数据依赖计算(如购物车总价)。
- 侦听器 (watch):无缓存,监听数据变化执行副作用。适用于异步请求、监控地址栏改变等。
- Watch 两大属性:
deep:深度监听对象变化。immediate:立即执行一次回调。
浏览器运行机制
- 进程:主进程(管理标签页)、渲染进程(每个标签页独立)、GPU 进程、插件进程。
- 线程:GUI 渲染线程(布局绘制)、JS 引擎线程(执行脚本)、事件线程等。
- 单线程原因:JS 主要用于操作 DOM,多线程会导致复杂的同步问题(如两个线程同时修改同一 DOM)。Web Worker 允许创建子线程,但不能操作 DOM。
- 回流与重绘:
- 回流 (Reflow):布局改变(宽高、位置等),触发重绘。
- 重绘 (Repaint):样式改变但不影响布局(颜色、背景)。
- 优化:减少 DOM 操作,合并读写,使用 CSS transform 代替 top/left。
虚拟 DOM 与生命周期
- 虚拟 DOM:用 JS 对象描述真实 DOM,批量更新以减少浏览器 Reflow/Repaint 次数。
- 生命周期:
created:数据初始化完成,不可操作 DOM。mounted:DOM 挂载完成,可操作 DOM(如 Echarts 初始化)。updated:数据更新后,DOM 已更新。unmounted:组件销毁,清理定时器等资源。activated/deactivated:keep-alive缓存组件的激活/停用。
- 父子组件顺序:父 created -> 子 created -> 子 mounted -> 父 mounted。
- $nextTick:确保在下次 DOM 更新循环结束后执行回调。原理是利用微任务队列(Promise/MutationObserver)缓冲更新。
组件编程
- Props:父传子,单向数据流。禁止子组件直接修改 props。
- Emit:子传父,通知父组件交互。
- 插槽 (Slot):内容分发,增强组件灵活性。
- 通信方式:Props/Emit、Pinia/Vuex、Provide/Inject、EventBus(Vue 3 移除)、Ref/Parent 获取。
组合式 API (Composition API)
- ref vs reactive:
ref:包装基本类型或对象,访问需.value。reactive:包装对象,直接访问属性。
- watch vs watchEffect:
watch:懒执行,指定监听源。watchEffect:立即执行,自动追踪依赖。
路由 (Vue Router)
- 模式:Hash 模式(带 #,兼容性好)、History 模式(无 #,需服务器配置)、Abstract(服务端)。
- 原理:Hash 基于
location.hash监听;History 基于history.pushState。 - 导航守卫:
- 全局前置
beforeEach:权限校验。 - 路由独享
beforeEnter。 - 组件内
beforeRouteEnter/Update/Leave。
- 全局前置
- 动态路由:根据用户权限动态添加路由规则,实现菜单权限控制。
Axios 与 HTTP
- XHR vs Fetch:Fetch 基于 Promise,更现代。
- Axios:基于 Promise,支持拦截器、取消请求、自动转换 JSON。
- 跨域解决:前端代理(devServer)、后端 CORS 配置、JSONP(GET)。
- HTTP 状态码:2xx 成功,3xx 重定向,4xx 客户端错误,5xx 服务端错误。
- GET vs POST:GET 参数在 URL,不安全;POST 在 Body,更安全,适合提交敏感数据。
TypeScript 进阶
- Any vs Unknown:Unknown 更安全,使用前需类型检查;Any 可跳过检查。
- Type vs Interface:
type:类型别名,支持联合、交叉、字面量等复杂类型。interface:接口,主要用于描述对象结构,支持继承和扩展。
- 泛型应用:Vue ref/reactive、API 响应数据封装、React useState 等。
- 修饰符:public(默认)、private(类外不可见)、protected(子类可见)、readonly(只读)。
以上内容基于实际项目经验整理,旨在帮助开发者深入理解核心机制。

