2025 最新前端高频率面试题--Vue篇

1.v-for 和 v-if 可以混合使用吗?为什么?

可以,但是尽量不要同时使用

Vue2 中 v-for 计算优先级比 v-if 高,首先会把虚拟节点渲染出来,然后再进行 v-if 判断。降低渲染性能。

Vue3 中 v-if 的优先级高于 v-for ,但是也不推荐同时使用,官方文档推荐可以把 v-for 提到外面一层用 template 包裹,或者提高 v-if。

++两种混在一起写法均不被官方推荐使用。++

2、v-for 中为什么加 key?

如果不适用key,vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key是为Vue中vnode的唯一标记,通过这个key,diff算法可以更准确、更快速。

  • 更准确:因为带key就不是就地复用了,再sameNode函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
  • 更快速:利用key的唯一性生成map对象来获取对应节点,比遍历方式更快。
3.事件默认有个event参数,它是什么?怎么使用?事件被绑定到哪里?

当事件没有参数、则默认有个event参数:如果有自定义参数,则需要使用$event传递过去。

  • event的构造函数时MouseEvent,即是原生的event对象。
  • event被挂载到当前元素下,即event.target.
4.Vue父子组件如何通讯?
  • Props、$emit:

父组件使用动态数据传递,子组件使用props接收,可以使用数组/对象数据结构,对象结构可以定义类型和默认值。

子组件使用$emit事件回传。

  • 自定义事件进行组件通讯:

自定义事件就是使用一个额外的js文件,其中声明一个Vue实例即可。

on,emit,$off,参数分别是:注册函数名,真实函数。

$on:绑定自定义事件

$emit:调用自定义事件

off:在组件销毁时,要及时销毁自定义事件,否则可能会造成内存泄漏。在 beforeDestroy 中调用off

  • $refs:获取当前组件实例。
  • parentchildren:获取当前组件和父组件和子组件。
  • Vuex:Vue中全局状态管理系统,用于多个组件中数据共享。
  • provide&inject:上层组件提供,下层组件注入使用。(适用于组件库编写)
5、父子组件声明周期调用顺序?
  • 加载渲染过程:

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

  • 更新过程:

父beforeUpdate->子beforeUpdate->子updated->父updated

  • 销毁过程:

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

  • 全流程:

beforeCreate->created->beforeMount->mounted->beforeUpdate->updated->beforeDestory->destroyed

6、Vue双向绑定原理(响应式原理)?

采用数据劫持结合观察者模式的方式

通过Object.defineProperty()来劫持各个属性(只会劫持已经存在的属性)的setter、getter、dep和Watcher实现依赖收集和派发更新的过程:

  • Vue将data初始化为一个observer并对对象中的每个值,重写了其中的get、set、data中的每个key,都有一个独立的dep(依赖收集器)。
  • 在get中,向dep(依赖收集器)添加了监听
  • 在mount时,实例了一个Watcher,将收集器的目标指向了当前Watcher
  • 在data值发生变更时,触发set,触发了dep(依赖收集器)中的所有监听的更新,来触发Watcher.update
7、$nextTick是什么?为什么优先解决微任务?

nextTick中的回调是在下次Dom更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的Dom。主要思路就是采用微任务优先的方式调用异步方法去执行nextTick包装的方法

8、Vuex是什么?为什么要使用?

Vuex是专门为Vue提供的全局状态管理系统,用于多个组件中数据共享、数据缓存等。(无法持久化、内部核心原理是通过创造一个全局实例new Vue)

主要包括以下几个模块:

  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter:允许组件从Store中获取数据,MapGetters辅助函数仅仅是将store中的Getter映射到局部计算属性。
  • Mutation:是唯一更改store中状态的方法,且必须是同步函数。
  • Action:用于提交mutation,而不是直接变更状态,可以包括任意异步操作。
  • Module:允许将单一的Store拆分为多个store且同事保存在单一的状态树中。
9、keep-alive是什么?怎么实现的?生命周期?首次加载是先执行activated还是deactivated,为什么?

作用与用法:

开发中缓存组件使用keep-alive组件,keep-alive是Vue内置组件,keep-alive包裹动态组件Component时,会缓存不活动的组件实例,而不是销毁它们,这样在组件切换过程中将状态保留在内存中,防止重复渲染Dom。

使用细节:

结合属性include和exclude可以明确指定缓存哪些组件或排除缓存指定组件。Vue3中结合Vue-router时变化较大,之前时keep-alive包裹router-view,现在需要反过来用router-view包裹keep-alive.

keep-alive的中缓存的时候还运用了 **LRU(Least Recently Used)**算法。

LRU(最近最少使用)缓存机制:

如果关键字key存在于缓存中,则返回关键字的值,否则返回-1。如果关键字已经存在,则变更其数据值;如果关键字不存在,则拆入该组 [关键字-值]。当缓存容量达到上限时,它应该在写入新数据之前删除最久为使用的数据值,从而为新的数据值留出空间。

组件缓存后更新,解决方案可以有以下两种:

  • beforeRouteEnter:在有Vue-router的项目,每次进入路由的时候,都会执行beforeRouteEnter。
  • activated:在keep-alive缓存的组件被激活的时候,都会执行activated钩子。

原理:

keep-alive是一个通用组件,它内部定义了一个map,缓存创建过的组件实例,它返回的渲染函数内部会查找内嵌的component组件对应组件的vnode,如果该组件在map中存在就直接返回它。由于component的is属性是个响应式数据,因此只要它变化,keep-alive的render函数就会重新执行。

参数:

keep-alive接收三个参数:

  • include:可传字符串、正则表达式、数组、名称匹配成功的组件会被缓存
  • exclude:可传字符串、正则表达式、数组、名称匹配成功的组件不会被缓存
  • max:可传数字,限制缓存组件的最大数量,超过 max 则按照 LRU 算法进行置换

include 和 exclude,传数组情况居多。

生命周期:

生命周期有activated激活、deactivated离开

  • activated:页面第一次进入的时候,钩子触发的顺序是create->mounted->activated
  • deactivated:页面退出的时候会触发deactivated

当再次前进或者后退的时候只触发activated。

使用keep-alive会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在activated阶段获取数据,承担原来created钩子中获取数据的任务。那么,我们一般会在动态组件、路由组件去用到keep-alive组件。

10、Vue2和Vue3的区别?
  • 响应式系统:Vue2是object.defineProperty();Vue3使用的是proxy
  • Vue3全部由ts重构,对ts支持更友好
  • 自定义渲染器
  • composition Api
  • vue3可以存在多个根节点,Vue2只能有一个
11、history和hash路由实现原理?区别是什么?

hash模式:

1.location.hash的值实际就是URL中#后面的东西 它的特点在于:hash虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不回重新加载页面。

2.可以为hash的改变添加监听事件

每一次改变hash(window.location.hash),都会在浏览器的访问历史中增加一个记录。

利用hash的以上特点,就可以来实现前端路由"更新视图但不重新请求页面"的功能了

特点:兼容性好但是不美观

history模式

利用了HTML5 History InterFace中新增的pushState()和replaceState()方法。

这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go的基础之上,它们提供了对历史记录进行修改的功能。这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后虽然当前URL改变了,但浏览器不会刷新页面,这就为单页应用前端路由"更新视图但不重新请求页面"提供了基础。

特点:虽然美观,但是刷新会出现4.4需要后端进行配置

12、请说出常用的设计模式?(5 种以上)并举例实际项目中的使用场景。
  • 1.工厂模式 - 传入参数即可创建实例

虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode

  • 2.单例模式 - 整个程序有且仅有一个实例

vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉

  • 3.观察者模式 (响应式数据原理)
  • 4.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略
  • 5.策略模式:优化 if else 冗余代码
  • 6.代理模式:mini-vue proxy
13、emit 和 on 的本质?
  • 1.on、emit 基于发布订阅模式
  • 2.$on 用来收集所有的事件依赖,他会将传入的参数 event 和 fn 作为 key 和 value 的形式存到 vm._events 这个事件集合里,就像这样 vm._events[event]=[fn];
  • 3.而 $emit 是用来触发事件的,他会根据传入的 event 在 vm_events 中找到对应的事件并执行 invokeWithErrorHandling(cbs[i], vm, args, vm, info)
  • 4.最后我们看 invokeWithErrorHandling 方法可以发现,他是通过 handler.apply(context, args) 和 handler.call(context) 的形式执行对应的方法
14、虚拟 dom 是什么?原理?优缺点?

用 js 模拟一颗 dom 树,放在浏览器内存中.当你要变更时,虚拟 dom 使用 diff 算法进行新旧虚拟 dom 的比较,将变更放到变更队列中,反应到实际的 dom 树,减少了 dom 操作。

虚拟 DOM 将 DOM 树转换成一个 JS 对象树,diff 算法逐层比较,删除,添加操作,但是,如果有多个相同的元素,可能会浪费性能,所以,react 和 vue-for 引入 key 值进行区分。

优点

  • 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
  • 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
  • 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等。

缺点

无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入慢。

15、mixin 是什么?优缺点?原理?vue3 用什么取代了?

组件和组件之间有时候会存在相同的代码逻辑,分为局部混入全局混入 ,我们希望对相同的代码逻辑进行抽取

  • Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能
  • 一个 Mixin 对象可以包含任何组件选项 --- 其本质就是一个对象
  • 当组件使用 Mixin 对象时,所有 Mixin 对象的选项将被 混入该组件本身的选项中

缺点:

  • 变量来源不明确,不利于阅读
  • 多 mixin 可能会造成命名冲突
  • mixin 和组件可能出现多对多的关系,复杂度较高

Vue3 使用 Composition API 替代了,优点:

  • 代码提取
  • 代码重用
  • 命名冲突解决
16、自定义指令?原理?

Vue 自定义指令有全局注册和局部注册两种方式。先来看看注册全局指令的方式,通过 Vue.directive(id, [definition]) 方式注册全局指令。然后在入口文件中进行 Vue.use() 调用。

它的作用价值在于当开发人员在某些场景下需要对普通 DOM 元素进行操作。提高代码复用。

指令本质上是装饰器,是 vue 对 HTML 元素的扩展,给 HTML 元素增加自定义功能。vue 编译 DOM 时,会找到指令对象,执行指令的相关方法。

自定义指令有五个生命周期(也叫钩子函数),分别是 bind、inserted、update、componentUpdated、unbind

  • 1.bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • 2.inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • 3.update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
  • 4.componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  • 5.unbind:只调用一次,指令与元素解绑时调用。

原理

  • 1.在生成 ast 语法树时,遇到指令会给当前元素添加 directives 属性
  • 2.通过 genDirectives 生成指令代码
  • 3.在 patch 前将指令的钩子提取到 cbs 中,在 patch 过程中调用对应的钩子
  • 4.当执行指令对应钩子函数时,调用对应指令定义的方法
17、事件绑定原理?

on、emit 是基于发布订阅模式的,维护一个事件中心,on 的时候将事件按名称存在事件中心里,称之为订阅者,然后 emit 将对应的事件进行发布,去执行事件中心里的对应的监听器

18、$set 的原理?

因为响应式数据 我们给对象和数组本身都增加了 ob 属性,代表的是 Observer 实例。当给对象新增不存在的属性 首先会把新的属性进行响应式跟踪 然后会触发对象 ob 的 dep 收集到的 watcher 去更新,当修改数组索引时我们调用数组本身的 splice 方法去更新数组

19、Vue3 比 Vue2 有什么优势?
  • 1.性能更好
  • 2.体积更小
  • 3.更好的 TS 支持
  • 4.更好的代码组织
  • 5.更好的逻辑抽离
  • 6.更多新功能
20、Vue3 声明周期
  • Options API
  1. beforeDestroy 改为 beforeUnmount
  2. destroyed 改为 unmounted
  3. 其他沿用 Vue2 的生命周期
  • Composition API

setup 相当于整合了 beforeCreate 和 created

其余生命周期分别是写在 setup 中的函数:

  1. onBeforeMount()
  2. onMounted()
  3. onBeforeUpdate()
  4. onUpdated()
  5. onBeforeUnmount()
  6. onUnmounted()
21、Composition API 和 Options API
  • 1.更好的代码组织
  • 2.更好的逻辑复用
  • 3.更好的类型推导

如何选择?

  • 1.不建议共用,会引起混乱
  • 2.小型项目、业务逻辑简单,用 options API
  • 3.中大型项目、逻辑复杂,用 composition API
22、如何理解 ref、toRef 和 toRefs
  • ref:
  1. 生成值类型的响应式数据
  2. 可用于模版和 reactive
  3. 通过.value 修改值
  • toRef:
  1. 针对一个响应式对象(reactive 封装)的 prop
  2. 创建一个 ref,具有响应式
  3. 两者保持引用关系
  • toRefs:
  1. 将响应式对象(reactive 封装)转换为普通对象
  2. 对象的每个 prop 都是对应的 ref(不然 reactive 响应式直接解构会失去响应式)
  3. 两者保持引用关系
23、为何 ref 需要 value 属性?
  • 1.ref 是一个对象(不丢失响应式,值类型不能用 proxy 代理),value 储存值
  • 2.通过 .value 属性的 getset 实现响应式
  • 3.用于模版、reactive 时,不需要 .value,其他情况都需要
24、Vue3 升级了哪些重要的功能?
  1. createApp
  2. emits 属性:在子组件中声明 emits options 父组件的绑定事件
  3. 生命周期:使用 setup 整合 beforeCreate 和 created``,beforeDestroy 改为 beforeUnmount,destroyed 改为 unmounted,其他与 vue2 一致
  4. 多事件处理:在点击事件中写入多个处理函数,用逗号分割
  5. Fragment:可以存放多个根节点
  6. 移除 .sync
  7. 异步组件的写法:需要从 Vue 引入 defineAsyncComponent,使用这个函数包裹 import() 引入异步组件
  8. 移除 filter:双括号中用 | 分割转换含义
  9. Teleport:主要场景就是把组件的嵌套层级提高
  10. Suspense:用来加载异步组件未成功时的一些 loading,主要实现原理就是具名插槽
  11. Composition API
25、虚拟Dom:

就是根据template这个标签来生成的 template是咱们想要真实Dom什么样子就写成什么样子 template里边的数据可不是真实dom,是虚拟dom就是对真实dom的一个描述。 虚拟Dom你优化渲染性能的,能够有效的比较和更新真实Dom的内容 从而减少真实Dom的操作和提高应用性能、能够用diff算法 精确的找到哪里发生了变化 然后直接更新真实dom、

26、MVVM的理解:
  • Model:模型层,负责处理业务逻辑以及和服务器进行交互。
  • View:视图层,负责将数据模型转化成UI显示出来,可以简单的理解为HTML页面
  • ViewModel:试图模型层,用来连接Model和View,是Model和View之间的桥梁,每当V层获取或者保存数据的时候,都要由VM层做中间的处理,从而交给M层。

**总结:**MVVM模式简化了界面和业务的依赖,解决了数据频繁更新。MVVM在使用当中,利用了双向绑定技术,使得Model在变化时,ViewModel会自动更新,而ViewModel变化时,View也会自动变化。

27、事件循环机制:

事件循环机制的基本原理是,当用户与页面交互或数据发生变化时候 Vue.js 会将这些事件加入到一个事件队列中,并在适当的时机执行这些事件。Vue.js 使用了一种称为"虚拟 DOM"的技术,它能够在内存中维护一个虚拟的 DOM 树,当数据发生变化时,Vue.js 会比较新旧虚拟 DOM,然后只更新需要更新的部分,以提高性能和效率。

28、闭包:

闭包就是有权访问另一个函数作用域中内部变量或数据的函数,因为在JS中,只要内部函数能能够读取外部函数的变量或数据,反之就不行,所有可以将闭包简单理解成,定义在一个函数内部的函数。

29、对于异步理解:

异步操作是指不会立即返回结果的操作

  1. 回调函数(Callback):回调函数 最早处理异步操作的方式 在异步操作完成后,通过调用预先定义的回调函数来处理结果
  2. Promise: 它通过对象的状态(Pending、Fulfilled、Rejected)来表示异步操作的执行结果。Promise 提供了链式调用的方法,可以更清晰地表达异步操作的执行顺序和错误处理逻辑
  3. async/await: async/await 是 ES2017 中引入的异步编程语法糖,它基于 Promise,使异步代码看起来像同步代码一样,更加易读和易理解。通过 async 声明异步函数,并在其中使用 await 来等待异步操作的结果
    总结: 理解异步编程的关键在于理解事件循环(Event Loop)。JavaScript 是单线程执行的,意味着同一时间只能执行一个任务。当遇到异步操作时,JavaScript 将其放入任务队列中,并继续执行后续代码。当主线程空闲时,事件循环会从任务队列中取出任务执行。
30、箭头函数和普通函数有什么区别?
  1. 语法:箭头函数使用箭头(=>)来定义函数,而普通函数使用关键字 function来定义
  2. 写法:箭头函数可以是一个表达式,也可以是一个代码块。如果是表达式,函数体中的表达式会被隐式地返回。普通函数使用大括号包裹函数体,并使用 return 关键字来指定返回值
  3. this 的指向:箭头函数没有自己的 this 绑定,它会继承外层作用域的 this 值。而普通函数的 this 值是在运行时动态绑定的,根据函数的调用方式决定。
相关推荐
崔庆才丨静觅13 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606113 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了14 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅14 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅14 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅14 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment14 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅15 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊15 小时前
jwt介绍
前端
爱敲代码的小鱼15 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax