前端面试题10.25

Vue的渲染过程

Vue的渲染过程主要分为以下几个步骤:

1)创建Vue实例:通过new Vue()创建Vue实例,进行初始化。

2)模板编译:Vue会将模板(template)编译成渲染函数(render function),这个过程可以通过Vue的编译器或者手动使用render函数来完成。

3)数据响应式:Vue会对data中的数据进行响应式处理,即通过Object.defineProperty()方法将数据转化为getter和setter,当数据发生变化时,能够触发依赖该数据的视图更新。

4)虚拟DOM生成:Vue会根据模板和数据生成虚拟DOM(Virtual DOM),虚拟DOM是一个轻量级的JavaScript对象,它描述了真实DOM的结构和属性。

5)虚拟DOM更新:当数据发生变化时,Vue会重新生成虚拟DOM,并与之前的虚拟DOM进行比较,找出差异(Diff算法),然后只更新发生变化的部分,而不是直接操作真实DOM。

6)真实DOM更新:最后,Vue会将更新后的虚拟DOM渲染到真实的DOM上,完成视图的更新。

Vue的双向绑定的核心设计原理

Vue的双向绑定是通过数据劫持和发布订阅模式实现的。

在Vue中,通过Object.defineProperty()方法对data中的数据进行劫持,将数据转化为getter和setter。当数据发生变化时,会触发setter方法,setter方法会通知依赖该数据的视图进行更新。

同时,Vue还通过发布订阅模式实现了数据的订阅和通知。在Vue中,每个响应式数据都有一个对应的Dep对象,Dep对象维护了一个存储Watcher对象的数组。当数据发生变化时,会通知Dep对象,然后Dep对象会遍历调用存储的Watcher对象的update()方法,进而触发视图的更新。

通过数据劫持和发布订阅模式的结合,Vue实现了双向绑定,即数据的变化能够自动反映到视图上,同时视图的变化也能够更新数据。

发布订阅模式

发布订阅模式是一种常用的设计模式,用于解耦事件的发送者和接收者。

在发布订阅模式中,存在一个事件中心(或称为消息中心),负责管理事件的订阅和发布。事件的发送者(发布者)将事件发布到事件中心,事件的接收者(订阅者)通过订阅事件来接收并处理事件。

具体流程如下: 1)订阅者通过调用订阅方法(subscribe)来订阅感兴趣的事件,并指定相应的回调函数。 2)发布者在适当的时机通过调用发布方法(publish)来发布事件,并将事件的相关数据传递给订阅者。 3)事件中心接收到事件后,根据订阅者的订阅信息,将事件分发给对应的订阅者。 4)订阅者收到事件后执行相应的回调函数进行处理。

发布订阅模式的优点是解耦了事件的发送者和接收者,使得系统更加灵活可扩展。在前端开发中,发布订阅模式常用于组件之间的通信、事件的监听和触发等场景。

事件代理

事件代理(委托)是一种常用的优化技术,通过将事件绑定在父元素上,利用事件冒泡机制,实现对子元素的事件监听和处理。

具体原理如下: 1)将事件绑定在父元素上,例如将点击事件绑定在父元素的click事件上。 2)当子元素触发相应的事件时,事件会依次向上冒泡到父元素。 3)父元素捕获到事件后,通过判断事件源(即触发事件的具体元素)来执行相应的处理逻辑。

事件代理的优点是减少了事件绑定的数量,尤其在大量子元素存在的情况下,可以提升性能和减少内存占用。此外,事件代理还可以动态绑定和解绑事件,方便管理和维护代码。

Vue组件传值的方式,具体业务场景

在Vue中,组件之间的传值可以通过以下几种方式实现:

1)Props:父组件通过props属性向子组件传递数据。适用于父子组件之间的单向数据流场景,父组件作为数据的源头,子组件接收并使用这些数据。

2)emit和自定义事件:子组件通过emit和自定义事件:子组件通过emit方法触发自定义事件,并携带需要传递的数据,父组件通过监听自定义事件来获取数据。适用于子组件向父组件传递数据的场景。

3)Provide和Inject:通过在父组件中使用provide提供数据,然后在子组件中使用inject注入数据。适用于祖先组件向后代组件传递数据的场景。

4)Vuex:Vuex是Vue官方提供的状态管理库,适用于大型应用中多个组件共享状态的场景。通过在Vuex中定义和修改状态,各个组件可以通过getter和mutation来获取和修改共享的数据。

具体选择哪种方式取决于业务需求和组件之间的关系。如果是父子组件之间的简单数据传递,props和$emit可以满足需求;如果是跨层级的组件传值,可以考虑使用Provide和Inject或者Vuex。

JS事件循环
JavaScript采用事件驱动的编程模型,事件循环是JavaScript中处理异步操作的机制。事件循环负责管理和调度各种事件和回调函数的执行顺序。

事件循环的过程如下:
1)执行同步代码:首先执行当前执行上下文中的同步代码,直到遇到异步任务。

2)执行微任务:当遇到异步任务时,将其注册为相应的异步事件,并继续执行后续的同步代码。在同步代码执行完毕后,会立即执行已注册的微任务队列中的所有微任务,包括Promise的回调函数、MutationObserver的回调等。

3)执行宏任务:当微任务执行完毕后,会检查是否有宏任务需要执行,如果有,则选择一个宏任务执行。常见的宏任务包括定时器回调、事件回调、Ajax请求等。

4)重复以上步骤:执行完当前宏任务后,再次执行微任务,然后选择下一个宏任务执行。不断循环执行,直到没有待执行的任务。

需要注意的是,微任务优先级高于宏任务,即在同一轮事件循环中,微任务会在下一个宏任务之前执行完毕。

Node.js事件循环:
Node.js的事件循环与浏览器中的事件循环类似,但存在一些差异。

Node.js的事件循环过程如下:
1)执行同步代码:首先执行当前执行上下文中的同步代码,直到遇到异步任务。

2)执行微任务:与浏览器环境类似,在同步代码执行完毕后,会立即执行已注册的微任务队列中的所有微任务。

3)轮询阶段(Poll):在此阶段,Node.js会检查是否有待处理的I/O事件、定时器等。如果没有,则会等待新的事件加入事件队列。

4)执行宏任务:当有待处理的I/O事件、定时器等时,会选择一个宏任务执行。执行完毕后,再次执行微任务。

5)检查阶段(Check):在此阶段,Node.js会执行setImmediate()方法注册的回调函数。

6)关闭阶段(Close):在此阶段,Node.js会执行一些关闭操作,比如关闭文件描述符、清理资源等。

与浏览器环境不同的是,Node.js的事件循环中存在轮询阶段和检查阶段,用于处理I/O事件和setImmediate回调函数。

深浅拷贝

深拷贝和浅拷贝是在复制对象或数组时使用的两种不同的拷贝方式。

浅拷贝是指创建一个新的对象或数组,新对象的属性或元素的值是对原对象或数组的引用。修改新对象中的属性或元素会影响到原对象。常见的浅拷贝方式有Object.assign()、Array.prototype.slice()、Array.prototype.concat()等。

深拷贝是指创建一个新的对象或数组,并且递归地复制原对象或数组中的所有属性或元素,新对象和原对象完全独立,互不影响。常见的深拷贝方式有JSON.parse(JSON.stringify())、lodash.cloneDeep()、手动递归复制等。

需要注意的是,使用JSON.parse(JSON.stringify())进行深拷贝时,会忽略函数、正则表达式、undefined等特殊类型的值,以及循环引用的情况。

猜你喜欢

转载自blog.csdn.net/m0_62742402/article/details/134040685