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

06-01 1119阅读
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:获取当前组件实例。
          • $parent$children:获取当前组件和父组件和子组件。
          • 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的改变添加监听事件

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

                                每一次改变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 属性的 get 和 set 实现响应式
                                                                    • 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 值是在运行时动态绑定的,根据函数的调用方式决定。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码