news 2026/10/17 5:49:25

Vue面试核心原理与高频题拆解:响应式、虚拟DOM、diff与组件通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue面试核心原理与高频题拆解:响应式、虚拟DOM、diff与组件通信

2021年那会儿,我把市面上能找到的Vue面试题和笔试题几乎刷了个遍,也帮身边不少朋友做模拟面试辅导,前前后后总结了一批高频考点和答题套路。现在回头看,虽然Vue 3生态已经成了主流,但Vue 2时代沉淀下来的核心原理,比如响应式数据、组件通信、虚拟DOM、diff算法这些,依然是前端面试绕不开的基本盘。甚至可以说,理解了Vue 2的响应式是怎么用Object.defineProperty实现的,再去看Vue 3的Proxy方案,理解的深度完全不一样。这篇文章结合我当年刷题的经验和实际面试官视角,把Vue相关的面试准备思路、高频题的拆解方法、笔试题的完整套路都系统梳理一遍,不管你现在面的是初级还是高级岗位,只要把这里面的逻辑吃透,应付大多数Vue技术面是够用的。

之所以强调逻辑而不是背题,是因为面试题这玩意儿更新速度极快,今天问你nextTick原理,明天就可能换个马甲问你watch和Watcher的关系。如果只背答案不建立知识网络,一换个问法就懵了。所以这篇不只是罗列题目,而是带着大家拆解题干、定位考点、组织答题结构,顺便把笔试题里那些手写代码的考察点也一并讲透。

1. 面试准备:先搞懂Vue考察的三个层面

1.1 面试官到底在考什么

先说一个很多人忽略的事实:面试官问Vue,目的往往不是考你对框架API记得多熟,而是通过Vue来考察你作为前端工程师的JavaScript基础、设计模式理解、工程化思维和排查问题的能力。这是国内前端面试一个非常典型的特点——框架是外壳,JS是内核。

举个例子,面试官问“Vue的data为什么是函数而不是对象”,表面上考的是Vue组件复用的设计,底层考的其实是JavaScript引用类型共享导致的污染问题。再比如问“computed和watch的区别”,表面上是API对比,实际在考你对响应式依赖收集的理解。很多初级候选人挂在这一步,就是因为把Vue当成了API手册来背,没有意识到面试官想听的是底层的“为什么”。

所以准备Vue面试,我建议按三层结构来搭建知识体系:

  • 第一层是框架层:生命周期、指令、组件通信、路由、状态管理这些能用API直接解决的问题。
  • 第二层是原理层:响应式原理、虚拟DOM、diff算法、模板编译、nextTick的实现机制。
  • 第三层是工程层:组件设计、性能优化、SSR、权限控制、状态管理的架构设计。

绝大多数面到第三轮的技术面,考察重心都落在第二层和第三层。第一轮笔试或机试反而更多是框架层的API和手写代码。这篇文章的节奏就按这个逻辑来:先把核心原理讲透,再拆高频面试题,最后用笔试题验证你的实操能力。

1.2 版本差异引发的考点变化

另一个必须提的点是版本。2021年时候,Vue 3已经正式发布了,但面试题库里Vue 2的内容仍然占了绝大多数。到了现在,Vue 3.4+都出来了,可很多面试官还在追问Object.defineProperty和Proxy的差异、Options API和Composition API的取舍。这说明什么?说明面试题有滞后性,但也说明核心原理有延续性。你准备Vue面试时,千万别只盯着一个版本,而是要理解Vue 2到Vue 3迁移过程中,哪些设计被保留、哪些被推翻、为什么推翻。这些问题才是真正拉开差距的地方。

我当年准备面试的一个笨办法:拿一张大纸,左边写Vue 2的做法,右边写Vue 3的做法,中间用箭头标出变化原因。比如:

  • 响应式:Object.defineProperty → Proxy,原因是无法检测新增/删除属性、数组索引变更、性能开销大。
  • 逻辑复用:mixins → Composition API,原因是命名冲突、来源不清晰、类型推导困难。
  • 全局API:Vue.prototype.$xxx → app.config.globalProperties,原因是多个实例时避免配置污染。
  • 异步组件:vue-router的component: () => import() → 显式defineAsyncComponent。
  • 片段:Vue 2组件必须单根节点 → Vue 3支持多根节点。

这种对比表刷完之后,几乎能手撕任何“谈谈Vue 2和Vue 3的区别”这类范围题。

2. 核心原理拆解:响应式、虚拟DOM与nextTick

2.1 响应式原理:从Object.defineProperty到Proxy

响应式原理基本上是Vue面试的必考题,占比极高。问法千变万化,但核心无非三层:怎么实现数据劫持、怎么收集依赖、怎么触发更新。Vue 2的实现路径是递归遍历data选项的所有属性,用Object.defineProperty把它们全部转为getter/setter。读取数据时触发getter,把当前Watcher收集到Dep里;修改数据时触发setter,通知Dep中的所有Watcher去更新视图。

这里有一个高频追问:为什么Vue 2无法监听数组的length变化?因为Object.defineProperty处理数组索引时,无法感知unshift、push这类修改数组本身的方法,Vue 2只能通过重写Array.prototype上的7个方法来变相解决。所以面试官如果追问“直接arr[0] = xxx能触发更新吗”,答案是很遗憾不行,必须用vm.$set或者重写后的方法。Vue 2里这个坑真的让很多人开发时踩过,尤其是从接口返回的数组直接赋值,经常出现修改数据但视图不更新的诡异情况。

Vue 3改用Proxy之后,这个问题从根上解决了。Proxy代理的是整个对象,新增属性、删除属性、数组索引变更都能被拦截。但Proxy也不是银弹,它无法自动处理嵌套对象,必须懒递归。所谓懒递归就是访问到某个属性是对象时,才递归为其创建Proxy代理,而不是像Vue 2一样初始化时一口气递归到底。这带来的性能收益非常可观。

面试时如果被问到“Vue 3为什么性能更好”,除了响应式的改变,还有静态标记和patchFlags优化。Vue 3编译模板时会标记动态绑定节点,diff阶段只比较带flag的节点,这一块的详细内容在后面的diff算法部分继续讲。

2.2 虚拟DOM与diff算法:为什么要有key

虚拟DOM也是Vue面试的常客。核心要点在于:直接操作真实DOM代价太高,浏览器重排重绘开销大,所以Vue在内存里维护一棵轻量的JS对象树,状态变化时先比较新旧两棵树,记录最小变更集,最后只动该动的真实DOM节点。

diff算法的过程其实是深度优先、同层比较。Vue 2的diff是双端比较,即新旧节点的首尾两两比较,试图少移动节点。Vue 3则用了一个更巧妙的长递增子序列算法来减少节点移动次数。这里面试官通常不会问得太深,但你要能讲清楚“同层比较”的大原则:跨层移动节点这种浪费性能的操作,框架故意不支持,让开发者通过v-if控制结构来规避。

然后就是key的作用,十个面试题里七个会问“为什么不能用index作为key”。关键点在于:diff算法可以根据key复用节点,如果只是用index做key,插入中间位置的节点时,会导致后续所有节点被重新渲染。举个例子,一个列表有a、b、c三个节点,key分别为0、1、2。在b和c之间插入d后,原来的c节点index从2变成3,新的d节点index是2。diff阶段会认为index=2的节点从c变成了d,于是c被卸载、d被创建,c之后的逻辑全部错乱。如果key使用唯一id,diff就能精确识别出d是新增节点,其他节点直接复用,性能好得多。

面试时这道题的答题结构建议:先解释key的作用(复用节点、追踪身份),再解释虚拟DOM对比时是同层级按key匹配,最后举具体示例展示index作为key导致的问题。这个递进关系讲完后,面试官基本不会追问太多。

2.3 nextTick的实现机制与使用场景

nextTick这个考点很有意思,它在面试题里经常以一个“场景解决题”出现:为什么拿到的DOM不是最新的?怎么解决?实际上这是Vue异步更新队列机制的延伸。

Vue更新DOM不是同步的。当你连续修改多次data时,Watcher不会被立即执行,而是会被推进一个队列里,然后通过微任务调度统一执行,这就是异步批量更新。好处是不用每次赋值都触发更新,性能好很多。但如果你在修改数据后立刻去获取真实DOM的高度或文本内容,会拿到旧值。nextTick就是在DOM更新完成后执行回调的途径。

手写nextTick的简易版本,核心就是微任务的模拟。当年很经典的考法是问“Vue的nextTick实现是微任务还是宏任务”,答作为微任务即可,但深入一点你最好知道:Vue 2内部会优先使用Promise.then,不支持Promise时降级为MutationObserver,再不行就setTimeout。Vue 3这里逻辑更简洁,但因为浏览器环境基本都有Promise,所以直接采用Promise。另外还会有一个细节追问:nextTick和await nextTick的作用完全一样,后者更方便写在async函数里。

实际工作中我常用nextTick配合第三方DOM库做图表初始化,或者弹窗打开后测量元素尺寸,这两类场景非常典型。如果面试时你还能顺口说出来自己踩过这种坑,并且有解决方案,基本这道题稳过。

3. 高频面试题分类解析:按答题思路拆解

3.1 computed、watch和methods的三者辨析

这是Vue面试里出现频率最高的一组对比题,没有之一。很多候选人能背出定义,但一被追问就露馅。我这里给出一份可以直接背下来用于口述的答题框架。

  • methods:普通函数,每次调用都重新执行,不缓存结果。适合事件处理逻辑,不适合做依赖数据变化的计算。
  • computed:计算属性,有缓存。依赖的响应式数据没有变化时,多次访问直接取缓存,不会重复执行getter。适合模板里复杂的表达式,比如购物车总价、过滤后的列表。
  • watch:侦听器,当侦听的源发生变化时执行回调,适合处理异步逻辑或副作用,比如搜索联想、路由切换时的数据拉取。

面试追问的点往往在“computed为什么有缓存”。这要往上追溯到响应式的依赖收集机制:computed内部创建了一个特殊的Watcher,首次访问时执行getter,把计算结果缓存到this.value上,同时getter里访问的响应式数据会把该Watcher收集为依赖。当依赖变化时,只把computed Watcher的脏标记dirty置为true,并不会立刻重新执行。下次访问时发现dirty为true才重新计算,否则直接返回缓存的value。

还有一个容易混淆的点:computed能否执行异步任务?不能。computed的getter需要同步返回值,如果里面有异步逻辑,返回的是pending状态的Promise,语义就错了。所以面试时如果遇到“如果computed依赖的data需要请求接口怎么办”这种问题,正确回答是不应该用computed,应该用watch配合data中间变量,或者直接在状态管理里异步获取。

3.2 生命周期:从创建到销毁的完整链路与各自坑点

生命周期题是Vue面试的基础题,也是容易加分的题。面试官会考察生命周期整体顺序,也会问具体的“为什么这个数据在created里能访问,在beforeCreate里不能”这类细节。Vue 3里生命周期命名改成了onBeforeMount这种函数式写法,但底层时机基本对应。

一张表格把Vue 2和Vue 3对应关系整理出来,方便背诵:

Vue 2生命周期Vue 3写法触发时机与常用场景
beforeCreatesetup() 编译阶段实例初始化之前,data没初始化,很少用
createdsetup()data/computed可访问,未挂载DOM,适合发请求
beforeMountonBeforeMount挂载开始之前,模板已编译为render函数
mountedonMounted真实DOM挂载完成,适合操作DOM、初始化图表
beforeUpdateonBeforeUpdate数据更新前,可访问旧DOM
updatedonUpdated数据更新后,不要在这里改数据,会死循环
beforeDestroyonBeforeUnmount组件销毁前,清理定时器、解绑事件
destroyedonUnmounted组件销毁后,收尾逻辑
activated/deactivatedonActivated/onDeactivatedkeep-alive组件切换时触发

高频追问有两处。第一是请求应该在created还是mounted发?常规回答是created,因为此时data已经初始化,能拿到this,而且created到mounted之间不需要等DOM渲染,响应更及时。但注意,如果请求依赖DOM测量结果,那只能放mounted。第二是updated里为什么不能改数据?因为每次数据改动触发更新,更新完又进入updated,如果updated里再次改动数据,会无限循环。相关源码实现里有标志位控制,但原理上我们要避免这种结构性陷阱。

keep-alive相关的activated/deactivated和缓存渲染,也是很常见的一个进阶问法。activated在组件每次重新进入时触发,适合做tab切换时的数据刷新或状态恢复;deactivated在组件被缓存时触发,适合暂停计时器这类操作。

3.3 v-if与v-show、v-for与key的联动陷阱

v-if和v-show的对比是面试题里的“甜品题”,基本人手一题,但许多人答不完整。

  • v-if:真正的条件渲染,不满足条件时DOM根本不存在,切换时有创建和销毁的开销,惰性。
  • v-show:不管条件真假,DOM始终存在,只是切换display:none,初始渲染开销更大,但切换成本低。

因此频繁切换的场景用v-show,首屏渲染可能影响性能时用v-if。另一个对偶问题是v-if和v-for不要在同一元素上用。Vue 2的源码里v-for优先级高于v-if,所以v-if在每次循环中都会被计算,相当于每个节点都要判断一次,性能浪费。正确做法是使用计算属性先过滤列表,再用v-for渲染过滤后的结果。Vue 3里v-if优先级反过来了,虽然不会反复判断,但官方依然建议避免同时使用,因为语义上容易越描越乱。

v-for的另一个考点是用index作为key的问题,前面已经说透。这里补充一个很实用的经验:列表一旦涉及跨项操作(插入、删除、排序),必须用稳定且唯一的业务id做key。如果面试官现场让你写一个“从中间删除一条数据”的题目,能在解释里体现这个点的候选人会得到明显好感。

4. 组件通信全图谱:八种方案与适用场景选择

4.1 从props/$emit到provide/inject的完整链路

组件通信是Vue面试体量最大的板块,几乎每轮技术面都会涉及。你需要能在几秒钟内给出至少五六种通信方式,并且讲清楚每种方式的适用范围。

常见方案清单:

  • props / $emit:父子组件通信,父传子用props,子传父用$emit触发自定义事件。
  • ref / $refs:父组件直接访问子组件实例,可调用其方法、读取其数据,适合非受控的紧急需求。
  • $parent / $children:父子间直接链式访问,但耦合度太高,项目大了很容易变成“面条式代码”,不够推荐。
  • provide / inject:祖先组件提供数据,后代组件注入使用,适合跨层级,但数据流不透明,不适合做核心业务通信。
  • $attrs / $listeners:Vue 2中透传属性与事件给子组件,Vue 3里合并为$attrs,写组件库时用得最多。
  • event bus:Vue 2里new Vue()实例作为中央事件总线,适合无关系组件通信,但Vue 3移除了$on/$off,官方推荐用mitt替代。
  • Vuex / Pinia:全局状态管理,适合跨组件共享的真实业务状态,Vuex是Vue 2主流,Pinia是Vue 3推荐。

面试时如果你能把props和$emit的执行流程拆出来讲,会非常加分。流程是这样的:父组件把数据通过模板绑定传递到子组件props,子组件通过$emit触发一个事件名,父组件在模板里用@事件名监听,实现数据反向传递。这个模式本质是单向数据流的体现——数据从父到子,子不能直接改父的数据,只能通过事件“申请”父来改。

4.2 状态管理:Vuex核心概念与Pinia对比

Vuex是Vue生态中绕不开的考点,问法集中在state、getters、mutations、actions、modules五个核心概念的理解,以及为什么要用mutation而不是直接修改state。原因是Vuex需要保证状态变更的可追踪性,所有同步修改必须经过mutation,这样在devtools里才能形成清晰的时间旅行调试。

这里面试官常追问的一个点是“mutation必须是同步的,那异步请求的数据怎么处理”。答案是异步逻辑放actions,在actions里调用mutation。道理很简单,如果mutation支持异步,那devtools记录的前后状态对不上,最终状态到底由哪次mutation触发变成了黑盒,调试就失去了意义。

Vue 3时代Pinia逐渐成为主流。相比Vuex,它去掉了mutations,直接修改state,同时用了更简洁的store定义方式,组合式API写起来很舒服。面试被问到Vuex与Pinia对比时,可以从三点说:开发体验(组合式vs options)、去掉mutations后的可追踪性差异、类型推导上的提升。但也要客观说明,Pinia并非Vuex的“取代”,更多是Vue生态自然演进的产物,Vuex 4也还在更新维护。

4.3 路由进阶:导航守卫、懒加载与权限控制

vue-router在面试中的定位是工程能力考察,尤其喜欢考导航守卫配合权限控制的场景题。

先理清路由守卫的种类和顺序:全局前置守卫beforeEach、全局解析守卫beforeResolve、全局后置钩子afterEach,路由独享的beforeEnter,组件内守卫beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。执行顺序大概是:全局beforeEach → 路由beforeEnter → 组件beforeRouteEnter → 全局beforeResolve → 全局afterEach。我在一次模拟面试中发现很多候选人能说出守卫名字,但顺序串得乱七八糟,这其实面试官不怎么计较,更看重的是守卫里能否正确实现权限控制逻辑。

权限控制面试题的经典场景是:根据用户登录状态和角色,控制可访问路由。标准实现方式是前端路由表分为公开路由和权限路由两部分,登录时拉取用户角色,动态生成权限路由表,用router.addRoutes(Vue 2)或router.addRoute(Vue 3)挂载。每次路由跳转在全局前置守卫里校验token和路由的meta.requiresAuth字段,没登录就跳login页,登录了但无权访问就跳403页。

懒加载是路由性能优化考点。component: () => import('@/views/xxx.vue')这种写法本质是webpack的代码分割能力。面试官如果追问“懒加载的好处”,要答出三点:首屏bundle体积减小,按需加载每个页面的JS,避免首屏长时间白屏,同时利用浏览器缓存提高二次访问速度。还可以补一句对路由级懒加载与组件级懒加载的区分,比如弹窗组件也可以suspense方式懒加载。

5. 笔试题实操:从手写源码到代码改错

5.1 手写基础能力:响应式、事件总线、Observer模式

笔试题和面试题最大的不同,在于它要求你在有限时间内产出可运行代码。Vue笔试题最常见的几类:手写简易响应式实现、手写EventBus、实现一个简易Vuex、代码改错、实现一个组件并考察props/emit用法。

先看手写响应式。经典题目是:用Object.defineProperty实现一个简易的响应式对象,数据变了自动更新视图。难倒很多人的不是defineProperty本身,而是依赖收集的闭环。当年我总结了一份简易实现,笔试够用:

class Dep { constructor() { this.subs = []; } depend() { if (Dep.target) { this.subs.push(Dep.target); } } notify() { this.subs.forEach(watcher => watcher.update()); } } class Watcher { constructor(getter) { this.getter = getter; Dep.target = this; this.getter(); Dep.target = null; } update() { // 实际项目中这里会执行渲染更新逻辑 console.log('视图更新'); } } function observe(data) { if (Object.prototype.toString.call(data) !== '[object Object]') return; Object.keys(data).forEach(key => { let value = data[key]; const dep = new Dep(); observe(value); Object.defineProperty(data, key, { enumerable: true, configurable: true, get() { dep.depend(); return value; }, set(newValue) { if (newValue === value) return; value = newValue; observe(newValue); dep.notify(); } }); }); } // 使用示例 const data = { count: 1 }; observe(data); new Watcher(() => data.count); data.count = 2; // 输出:视图更新

这是一个极为简化的模型,但笔试时能写出Dep和Watcher两层结构,已经能证明你对响应式原理的理解。注意补充说明两点:真正的Vue里还有个id自增、去重队列异步更新的机制,但核心模式就是发布订阅;defineProperty需要闭包保存value和dep实例,这是很多人卡住的原因。

再来看EventBus。手写一个简单的事件总线,本质是发布订阅模式的JS实现:

class EventBus { constructor() { this.events = {}; } on(name, fn) { if (!this.events[name]) { this.events[name] = []; } this.events[name].push(fn); } off(name, fn) { if (!this.events[name]) return; if (!fn) { delete this.events[name]; return; } this.events[name] = this.events[name].filter(cb => cb !== fn); } emit(name, ...args) { if (!this.events[name]) return; this.events[name].forEach(cb => cb(...args)); } once(name, fn) { const wrapper = (...args) => { fn(...args); this.off(name, wrapper); }; this.on(name, wrapper); } }

些微的细节漏洞,比如once的实现很多候选人会写错,因为wrapper必须被off清除而不是原fn。这种小坑很能筛掉基础不牢的人。

5.2 代码改错题:同样的坑你会不会踩

笔试的代码改错题常聚焦在Vue 2的API特性和JS语言坑。我总结几个高频案例。

第一个:data已经不是对象了。很多候选人直接在组件里写data: { count: 0 },导致组件复用时的数据污染。正确是data() { return { count: 0 } }。

第二个:在computed里修改了依赖的数据。笔试题目给出一段代码,computed里对依赖的数组做了push操作,然后问副作用是什么。正确答案是computed的幂等性被破坏,每次依赖变化时会产生额外状态变更,还可能导致死循环。规范要求computed里的getter应当是纯函数,不修改响应式数据。

第三个:v-for循环中使用了v-model绑定子项属性,同时这个数组是从接口拿到的。如果用户在操作过程中修改了数组项,Vue 2可能不更新视图。这个案例最好拿到题里写出判断依据,并给出用计算属性派生成可写数组的解决方案。

第四个:props被直接修改了。Vue单向数据流禁止子组件直接修改props,笔试中经常以改错形式出现。要改成通过$emit通知父组件修改。

5.3 综合实战题:一个列表页的完整实现

还有一种笔试要求直接在线上实现一个完整组件,例如:实现一个用户列表,列表数据异步获取,支持关键字搜索和删除操作,展示状态为loading/empty。这题不仅考API,还考组件拆分、状态设计、错误处理与防抖。

合理的实现思路是这样的:拆成UserList父组件和UserCard子组件;父组件管理loading/error/list/filterText等状态;搜索时用watch监听filterText,配合防抖函数发请求;删除时在子组件触发delete事件,父组件更新列表。

这个题目可以带出一系列追问:防抖函数怎么实现?watch里的immediate为什么要写成true?请求竞态怎么处理?我能想到候选人最常栽的地方是没有处理竞态,快速输入时先发出的慢请求会覆盖后发出的快请求。常见的应对方案是在请求的回调里对比请求序号,或者直接AbortController取消旧请求,这类经验很能体现“资深感”。

6. 常见失误与避坑指南:面试中的反向踩雷

6.1 高频翻车点:解释不清楚的“黑话”

前端面试有个很奇特的现象,候选人掌握了很多术语,但真被要求解释时,反而一句话都说不清楚。Vue相关的典型黑话包括:虚拟DOM、diff、依赖收集、派发更新、异步更新队列、编译优化、patch、Hydration。

比如谈到“虚拟DOM”,候选人会背诵“用JS对象描述真实DOM”,但被追问“这句话在实践中怎么体现”就卡壳。我建议准备这些术语时,每个都准备一个“生活类比”和一段30秒的口语化解释。虚拟DOM的类比就是:你手里有一张装修图纸,墙面变了你不会直接先砸墙,而是先在图纸上改好,再拿图纸去施工队定点施工。

再比如“diff算法”,说成白话就是:两个版本的老照片放在一起找不同,但只允许从上往下找,不允许先放大看局部细节。这张照片就是虚拟DOM树。

6.2 面试节奏控制与答题结构

面试时难免紧张,一旦遇到不会的题就慌。我的经验是每条技术问题都套同一个答题框架:先说结论,再说原因,最后举实例。结论控制在两三句话内,让面试官知道你有方向;原因要充分展示思考链路;实例用自己在项目里的真实经历最佳,项目名不用具体,但业务逻辑要清晰。

举个例子,面试官问“Vue的key有什么用”。结论:“key用于标识虚拟DOM节点的身份,辅助diff算法精准复用节点。”原因:“diff比较新旧vnode列表时,通过key判断两个节点是否同一节点,避免用index导致的索引错位。”实例:“我之前在开发列表页时,用index做key导致插入一行数据后整列闪烁,改用业务id后稳定了。”

这套“结论-原因-实例”结构不仅适用于Vue,也适用于任何技术面试题。建议自己在纸上把高频题提前演练一遍,磨嘴皮子。

6.3 无论笔试还是面试,这份清单考前过一遍

最后整理一份考前速查清单,我当年几乎是进面试间前30分钟快速扫一遍:

  • data在组件里必须是函数;props单向;$emit命名用kebab-case。
  • 计算属性有缓存,侦听器适合副作用;两者都可以依赖多个数据。
  • v-for动态渲染需要本地唯一key,不能滥用index。
  • 生命周期中mounted适合DOM操作,created适合初始化数据请求。
  • 组件通信不滥用EventBus,优先props/emit和状态管理。
  • Vuex的mutation必须同步,actions可以异步;Pinia没有mutations。
  • 路由守卫执行顺序清楚;权限控制用addRoute动态挂载。
  • 响应式原理要能自己写出最小实现。
  • nextTick解决DOM更新时机问题。
  • Vue 2和Vue 3差异从响应式、逻辑复用、全局API三方面展开。

这个清单是我多次面试复盘后浓缩出来的。当年我自己参加模拟面试,被问到最多的问题是“你说说Vue 2和Vue 3的响应式区别”,我在那上面讲了五分钟,后来所有类似问题我都沿用了这五分钟的叙事结构:从defineProperty的缺陷讲到Proxy的改进,再举一个数组下标赋值触发失败的例子,面试官通常会眼睛一亮。

刷题这条路没有捷径,但方向比努力更重要。只要把上面这些知识模块吃透,再多做几轮针对性的模拟问答,我相信你在Vue面试中的表现会比大多数候选人扎实一截。说白了,面试考的不只是知识本身,更是你面对未知问题时的拆解能力——能把这个能力在日常学习中训练出来,你就赢了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 5:49:09

HarmonyOS实战:算术闯关App串联状态管理、路由与组件生命周期

做了几十个独立的小功能之后,很多人会遇到一个共同的瓶颈:单个知识点都看得懂,但真要组合成一个完整应用,脑子里还是一团浆糊。我身边就有同事卡在“组件会写了,路由也会跳了,状态管理背了一堆概念&#xf…

作者头像 李华
网站建设 2026/10/17 5:48:54

Kotlin 与 Flutter 移动端开发选型深度对比:从原理到实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 5:48:27

Spring Boot+Shiro+CAS单点登录生产实践:多应用与分布式会话

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 5:48:25

ARMv8-M TrustZone 双世界工程从零实现:SAU配置与安全调用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 5:48:07

基于MP2642GR-Z与MK24FN256VDC12的储能电池主动均衡系统设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 5:47:40

Python爬虫实战:网易云音乐数据采集与结构化存储

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华