VUE3面试题

  1. vue3的编译流程?
  2. vue3内的宏是什么?
  3. script setup 的实现原理?
  4. 组件实例是什么?
  5. 启动程序的时候,vue3单文件组件的初始化流程?
  6. createApp(),mount()做了什么工作?
  7. 组件的生命周期?
  8. 什么是虚拟DOM?diff算法?就地复用?
  9. 任务调度系统?
  10. 异步刷新是什么?怎么实现的?
  11. nextTick()的实现原理?
  12. 有哪三种Effect?作用?
  13. watch(),watchEffect(),computed()的区别?
  14. 响应式编程的实现原理?
  15. ref()和reactive()的区别?
  16. ref()和ref(null)的区别?
  17. attrs和props的区别?
  18. provide和inject实现原理?
  19. emit()的实现原理?
  20. 单向数据流的原因?
  21. 模板的编译流程?在什么时候编译?
  22. 组件的注册是什么?
  23. 指令的实现原理?
  24. 各种指令的区别和作用?
  25. v-for为什么要加key?v-for为什么不能和v-if一起使用?
  26. v-model的实现原理?
  27. hook是什么?
  28. 插件是什么?实现原理?
  29. 什么是异步组件?实现原理?
  30. 前端路由是什么?什么是路由懒加载?

(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初始化实例的props、attrs、slots成员;然后执行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:computedEffect、watchEffect、renderEffect。正是通过这些Effect才实现数据可监听函数的绑定,其中computedEffect、watchEffect在setup()期间创建,而renderEffect在onBeforeMount和onMounted之间创建。

(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)attrs和props的区别?

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

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

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

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

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

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

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

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

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

(22)组件注册是什么?

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

(23)指令的实现原理?

vue3内的指令是,本质上是一系列钩子函数的集合,可以为这些钩子函数指定执行时机,包括:onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount和onUnmounted。

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

v-show和v-if的区别:v-show=false的组件会被创建,但是不会显示;v-if=false的组件不会被创建。v-on和v-bind的区别:v-on用于绑定事件和事件处理函数;v-bind用于绑定变量。v-text,v-html和插值表达式的区别:插值表达式存在闪屏的问题,而v-text 、v-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实现了数据双向绑定,其它地方实现的都是单向绑定,框内的文字发生变化,不会实时同步到数据上。在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包会变得非常大,会使得页面首次加载的时间变长 。若将不同路由对应的组件分割成不同的文件,然后当路由被访问的时候才从服务器加载对应文件,这就是路由的懒加载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值