面试题

144 阅读5分钟

Vue2的生命周期?

'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
'activated',
'deactivated',
'errorCaptured', // 错误监听
'serverPrefetch' // ssr 渲染需要的钩子

Vue2源码中Dep类

一个用于用于管理依赖跟踪和触发更新的类。
收集依赖:属性的 getter 中,Dep负责收集依赖到当前正在计算的观察者(`Dep.target`),也就是watcher。当属性被访问时,会将当前的观察者添加到 `Dep` 的依赖列表中(depend())。
派发更新:属性的 setter 中,`Dep` 负责通知依赖于该属性的观察者进行更新。当属性被修改时,会遍历 `Dep` 的依赖列表,逐个调用观察者的更新方法(`update()`)。

Vue2中watch和computed

本质都是watcher观察者,userWatcher、computedWatcher
watch:对数据变化做出响应,并执行相应的操作。
computed:基于现有的响应式数据计算和派生出新的数据,具有缓存机制。

Vue2中的指令

常见的,v-show、v-if、v-bind等
自定义指令可以用来权限处理(v-auth)、验证input输入框(v-number)
自定义指令多数会用到策略模式
vue的render函数或者jsx语法也能够写指令

v-model

本质是语法糖,v-model本质是emit了一个@input方法
<input type="text" v-model="value" />
等价于
<input type="text" :value="value" @input="value = $event.target.value"

Vue中性能优化方式

具体针对项目吧
加key渲染
懒加载路由、异步组件
避免不必要的响应式数据
图片CDN
webpack优化等
总的来说,先实现功能再考虑优化

讲讲Vuex

专门为Vue开发的全局状态管理,采用集中式存储管理应用状态,并以响应式的方式进行管理和操作。
Vuex 主要解决了组件之间共享状态、状态变更的追踪和管理的问题。
State:全局状态。
Getter:获取state的数据,可以理解为是Vuex的计算属性。
Mutation:修改状态的唯一方式,不能做异步操作。
Action:提交Mutation,这里可以进行异步操作,处理业务逻辑。
Module:将状态进行模块化,子模块都拥有上面这些。更灵活,方便维护。

Vuex和Redux的区别

相同点:都是用来做状态管理的,都是单向数据流模式
不同点:

框架集成:
Vuex:专门为Vue开发的,通过Vue的插件(Vue.use)机制进行集成,可以与Vue组件进行双向绑定,生态体系较小。
Redux:独立的库(Vue、React、Angular都可以用),没有任何特定框架的概念,React中使用Redux需要使用React-Redux库来与React进行集成。拥有庞大,活跃的生态体系。
语法:
Vuex:更接近Vue的风格,使用基于对象的方式进行状态管理
Redux:采用了纯函数的方式
响应式更新:
Vuex:使用Vue的响应式系统来更新视图,当状态发生变化时,相应的组件会自动更新。
Redux:使用了不可变的数据结构,并通过纯函数的方式处理状态变化,需要通过订阅和派发机制来实现视图的更新。

总而言之,Vuex 和 Redux 都提供了一种集中式的状态管理方法,用于管理复杂应用程序的状态。选择使用哪个库取决于你的项目需求和所选择的 JavaScript 框架。如果你使用 Vue.js,那么 Vuex 是一个很好的选择。如果你需要一个独立的状态管理库,可以与多个框架一起使用,那么 Redux 是更为常见的选择。

Vue源码中常见的设计模式

单例模式:Vue实例,Vuex实例,事件总线Event Bus
观察者模式:响应式系统,使用了 Object.definePropertyProxy 来跟踪对象的变化,并在属性被访问或修改时通知相关的观察者。
发布订阅模式:Vue事件系统,组件之间可以通过发布事件和订阅事件的方式进行通信
适配器模式:指令(Directives)和过滤器(Filters)可以看作适配器模式的应用。它们提供一种将外部数据转换为适合视图渲染的形式的机制。
策略模式:switch case其实算一个简单的策略模式
代理模式:Vue3使用proxy对象来处理数据劫持
工厂模式:Vue.extend创建组件

虚拟DOM的优缺点

提高性能:虚拟DOM通过在内存中创建一个轻量级的DOM副本来进行操作和计算,避免直接操作真实DOM带来的性能损失。通过比较虚拟DOM与真实DOM的差异,最小化实际的DOM操作,减少了对页面重绘和回流的次数,从而提高了渲染性能。
简化开发流程:虚拟DOM使得前端开发更为简化和高效。通过使用虚拟DOM,开发者可以将关注点从手动更新DOM转移到更高级别的组件抽象上,而不必担心繁琐的DOM操作。这样可以加快开发速度、减少出错的可能性,并提高代码的可维护性和可读性。
跨平台兼容性:虚拟DOM的抽象层可以使前端应用具有更好的跨平台兼容性。无论是在网页端还是原生移动端,虚拟DOM都能提供一致的开发和渲染体验,简化了在不同平台上的开发和适配工作。
生态系统支持丰富:虚拟DOM在许多流行的前端框架和库中得到了广泛应用和支持。例如,React、Vue和Angular等框架都采用了虚拟DOM的概念,并提供了一系列相关的工具和生态系统。使用虚拟DOM可以借助这些框架和工具,获得强大的开发和调试功能。
额外内存消耗:虚拟DOM需要在内存中创建和维护DOM的副本,因此会增加额外的内存消耗。对于较复杂的应用程序和大型的DOM结构,虚拟DOM的内存开销可能较大。
初始渲染时间:使用虚拟DOM需要将真实DOM和虚拟DOM同步,这意味着在初始渲染时需要进行额外的初始化操作。相对于直接操作真实DOM,这可能会导致初始渲染时间稍微延长。
复杂性增加:虚拟DOM引入了额外的抽象层,需要额外的算法和逻辑来处理虚拟DOM的比较和更新。这增加了代码的复杂性,可能需要更多的学习和理解成本。
事件处理器的处理开销:虚拟DOM一般会在每个组件上绑定事件处理器,以跟踪用户事件的变化。当组件较多或事件较频繁时,处理器的绑定和解绑操作可能会引起一定的性能开销。
非直接操作真实DOM:虚拟DOM通过比较差异并批量更新真实DOM来实现高效的渲染,这意味着我们不能直接控制和操纵DOM元素。在某些特定的场景下,可能需要直接操作真实DOM来实现特定的效果,虚拟DOM则会引入一定的限制和不便。