Vue3面试题

(1)vue3编译流程?

vue3的编译分两部分:编译期和运行期。编译期间,先通过vue-loader把单文件组件编译成符合原生JavaScript语法的模块;运行期间,会通过内置的模板引擎对模板进行编译,生成 render()函数,且按照先父组件后子组件的顺序对模板进行编译。

(2)vue3内的宏是什么?和语法糖的区别?

按照vue3官方的说法, defineProps()defineEmits()defineExpose()都是宏,它们使用形式上和函数调用差不多,区别是,第一,这些宏不需要通过模块导入;第二,这些宏会在编译期被编译成符合JavaScript原生语法的代码。语法糖也会被编译成符合JavaScript原生语法的代码,vue3官方对这两者进行区分是因为,语法糖创建的是不曾有过的语法,而宏指的是给现有语法新的含义。

(3)<script setup/>的实现原理?

<script setup/>本质是 setup()函数的语法糖,vue-loader在编译期间会把 <script setup/>内的代码编译成 setup()函数,把 defineExpose()内指定的变量编译为setup()函数的返回值。

(4)组件实例是什么?

每个单文件组件都有一个组件实例,组件实例是用来存放组件状态的,可以在 setup()函数内,通过 getCurrentInstance()获取组件实例。

(5)启动程序的时候,vue3单文件组件的初始化流程?

单文件组件由组件实例、相应vnode、相应node三部分组成。初始化的时候,先创建组件的实例;接着用父组件vnode初始化实例的 propsattrsslots成员;然后执行 setup()函数;接着把模板编译成 render()函数;接着创建vnode;如果当前组件有子组件,则切换到子组件,重复上面的步骤;子组件都初始化完成后,把vnode同步到node上。

(6)createApp()mount()做了什么工作?

程序在初始化的时候会依次调用 createApp()mount()函数, createApp()负责执行平台相关的代码, mount()负责执行平台无关的代码。 createApp()主要做了两件事,第一,创建一个渲染器,它可用于把vdom转化为平台相关的界面代码;第二,返回一个 App实例。 mount()的作用就是,创建组件实例、vdom、完成依赖收集、并通过渲染器把vdom渲染成平台相关的界面代码。

(7)组件的生命周期?

单个组件的生命周期:初始化阶段,先执行setup函数初始化实例,接着执行 onBeforeMount,最后执行 onMounted;运行阶段,先执行 onBeforeUpdate,再执行 onUpdated;关闭阶段,先执行 onBeforeUnmount,再执行 onMounted
父子组件的生命周期:初始化阶段,先执行父组件的 onBeforeMount,然后执行子组件的 onBeforeMount,接着执行子组件的 onMounted,最后执行父组件的 onMounted;运行阶段、关闭阶段同理可推。

(8)什么是虚拟DOM?diff算法?

虚拟dom是用JavaScript语言描述的一个树形结构,用于缓存发生变化的响应式数据,当到达下次刷新周期的时候,一次性把所有发生变化的数据同步到实际dom上。diff算法是同步vdom和dom数据的算法,采用就地复用的策略实现高效同步。

(9)任务调度系统?

vue3内部维持了3类队列:pre队列------组件更新前置任务队列;queue队列------组件更新时的任务队列;post队列------组件更新后置任务队列。vue3内所有异步任务都会被推进这些队列,当本次宏任务执行结束的时候,会执行一个名为flushJob的微任务,该微任务会按照pre>queue>post的优先级,依次执行每个队列中的函数。

(10)异步刷新是什么?怎么实现的?

异步刷新指的是在响应式数据发生更改后,只更新vdom,不立即更新dom,当下一个刷新周期到来的时候,次性把所有发生变化的数据同步到实际dom上。
异步刷新是通过job队列+Promise+diff算法实现的,当响应式数据发生更改时候,会立即更新vdom上的数据,待下个刷新周期到来的前,开始执行flushJob微任务,flushJob会通过diff算法完成vdom和dom之间的数据同步。

(11)nextTick()的实现原理?

nextTick()作用是,让回调函数在下一次刷新DOM的时候,具体来说在onUpdated后执行。vue3内的nextTick()是通过Promise实现,当微任务flushJob把Job队列中的所有函数都执行完了后,nextTick()回调会被推入微任务队列,然后开始执行。

(12)有哪三种Effect?作用?

vue3组件内有3类Effect: computedEffectwatchEffectrenderEffect。正是通过这些Effect才实现数据可监听函数的绑定,其中 computedEffectwatchEffectsetup()期间创建,而 renderEffectonBeforeMountonMounted之间创建。

(13)watch()watchEffect()computed()的区别?

三者都用于实现数据和监听函数的绑定。原理上来说,三者的共同点是,都会在setup期间、即onBeforeMount之前,创建一个Effect对象,并执行依赖收集函数进行依赖收集。区别是,第一,watchEffect、computed的依赖收集函数和监听函数是同一个函数,而watch的依赖收集函数和回调函数是两个函数,这就导致了watchEffect和computed参数中的监听函数会在程序初始化期间执行一次,而watch参数中的监听函数默认不会执行;第二,computed参数中的监听函数在变量发生变化后立即执行,watchEffect、watch参数中的监听函数执行时机可由用户指定,可以立即执行,也可以异步执行。

(14)响应式编程的实现原理?

响应式编程的核心是通过发布订阅模式、Effect对象、重写get函数实现的。发布订阅模式实现数据和监听函数的绑定,Effect对象内封装有监听函数和调度策略,get函数则负责进行依赖收集和返回数据。

(15)ref()reactive()的区别?

两者都用于实现响应式变量,区别在于 reactive()只可以封装引用类型, ref()可以封装任意类型; reactive()通过 Proxy实现, ref()通过类封装,并重写 get/set实现。就目前而言,要访问 ref()封装的变量,需要通过 value函数获取。

(16)ref()ref(null)的区别?

ref()的作用是封装普通数据,实现响应式数据; ref(null)的作用是获取子组件实例。

(17)attrsprops的区别?

attrsprops的作用都是,以模板属性的形式,从父组件传递数据给子组件。区别是,子组件中获取从父组件传过来的 props数据,首先需要用 defineProps()声明,而获取 attrs数据不需要声明。 props的优势是增加了代码可读性, attrs的优势是传值更灵活、代码更简洁。

(18)provide()inject()实现原理?

在祖先组件里通过 provide()提供的数据,可以在任意子孙组件里通过 inject()获取。它是通过原型链实现的。

(19)emit()的实现原理?

emit()是通过发布订阅模式实现的,子组件发送一个事件,父组件收到该事件会立即执行相应的函数。

(20)单向数据流的原因?

单向数据流指的是在 vue中约定,父组件传递给子组件的数据只能单向流动。也就是说,当一个父组件将其数据传递给一个子组件时,子组件不能直接修改该数据,而是需要通过向父组件发送事件来请求更改该数据。这种单向数据流的方式可以确保应用程序的数据流向清晰明确,易于理解和维护。

(21)模板的编译流程?在什么时候编译?

模板会先被解析成AST对象,然后通过遍历AST对象生成渲染函数。这个过程发生在 setup()函数执行结束后、 onBeforeMount之前。

(22)组件注册是什么?

若要在vue内使用自定义组件,需要先注册组件。组件注册可以看作是一种声明,用于告诉编译器,某个标签名是组件。组件注册分为局部注册和全局注册,全局注册的组件可以在整个程序内使用,局部注册的组件只可以在特定组件内使用。

(23)指令的实现原理?

vue3内的指令是,本质上是一系列钩子函数的集合,可以为这些钩子函数指定执行时机,包括: onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmounted

(24)各种指令的区别和作用?

v-showv-if的区别: v-show=false的组件会被创建,但是不会显示; v-if=false的组件不会被创建。
v-onv-bind的区别: v-on用于绑定事件和事件处理函数; v-bind用于绑定变量。
v-textv-html和插值表达式的区别:插值表达式存在闪屏的问题,而 v-textv-html不存在该问题;插值表达式和 v-text都会直接以字符串的形式显示html, v-html则可以渲染html标签对。

(25)v-for为什么要加key?v-for为什么不能和v-if一起使用?

v-for要加key是因为,第一,vue的同步算法采用就地复用的策略,在没有key值的情况下,diff算法认为标签类型相同的元素可以进行复用;有key值的情况下,diff算法认为标签类型相同且key值相等的元素才可以复用。第二,vue只在 v-model实现了数据双向绑定,其它地方实现的都是单向绑定, <input/>框内的文字发生变化,不会实时同步到数据上。
在vue3中, v-if的优先级高于 v-for,导致 v-if访问不了 v-for中的变量,因此不能把 v-if v-for 同时用在同一个元素上。

(26)v-model的实现原理?

v-model实现了数据的双向绑定,它是通过响应式数据+监听输入框事件实现的。

(27)hook是什么?

hook是一种编程封装思想,通过闭包实现,早在ES6诞生之前,这种编程封装思想在JavaScript中应用广泛,只不过在React17出现后,React官方把这种思想命名为hook,vue3借鉴react命名,也把这种封装思想称作hook。

(28)vue3插件是什么?

vue3内的所谓的插件不是常规意义上的插件,而是指mount()前执行的初始化函数,vue插件通常用来为 vue 添加全局功能。vue3内通过use()函数引入插件,use()的作用就是执行参数对象内的install()函数。

(29)什么是异步组件?

网页的渲染流程一般分两部,先从网络加载网页,然后渲染。异步组件指的是,首次加载和渲染网页的时候,不从网络上加载该组件对应的JavaScript文件,而是等到需要显示该组件的时候,再从网络上加载该组件并渲染显示出来。

(30)前端路由是什么?什么是路由懒加载?

路由能够根据不同的URL地址返回给用户不同的内容或页面,如果路由位于浏览器端,就是前端路由;如果路由位于服务器端,就是后端路由。
对于SPA单页应用,打包构建时,JavaScript包会变得非常大,会使得页面首次加载的时间变长 。若将不同路由对应的组件分割成不同的文件,然后当路由被访问的时候才从服务器加载对应文件,这就是路由的懒加载。

相关推荐
前端Hardy6 分钟前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
web Rookie36 分钟前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust44 分钟前
css:基础
前端·css
帅帅哥的兜兜44 分钟前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
工业甲酰苯胺1 小时前
C# 单例模式的多种实现
javascript·单例模式·c#
yi碗汤园1 小时前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称1 小时前
购物车-多元素组合动画css
前端·css
编程一生1 小时前
回调数据丢了?
运维·服务器·前端
丶21362 小时前
【鉴权】深入了解 Cookie:Web 开发中的客户端存储小数据
前端·安全·web
Missmiaomiao2 小时前
npm install慢
前端·npm·node.js