面试宝典--Vue2和Vue3的区别

266 阅读4分钟

面试宝典--computed和watch的区别

一. 根节点不同

Vue2中必须要有根标签;

Vue3中可以没有根标签,会默认将多个根标签包裹在一个fragement[ˈfræɡmənt]虚拟标签中,有利于减少内存。

注:Vue3之所以能够支持组件模板具有多个根标签,是因为Vue3在编译器层面上进行了一些改进和优化,在处理具有多个根元素的组件模板时,Vue3的编译器会将模板中的每个根级标签都编译为一个单独的标记片段。然后,这些标记片段将作为一个数组,一起创建实际的渲染函数。这样,每个根级标签都能够保留自己的作用域和响应式数据,并且它们可以并行地进行更新。

二. 组合式API和选项式API

在vue2中采用选项式API,将数据和函数集中起来处理,将功能点切割了当逻辑复杂的时候不利于代码阅读。

在vue3中采用组合式API,将同一个功能的代码集中起来处理,使得代码更加有序,有利于代码的书写和维护。

注: 选项API:代码风格:data选项写数据,methods选项写函数等,功能逻辑的代码分散;易于学习和使用;写代码的位置已经预定好;缺点是代码组织性差,相似的逻辑(功能)代码不便于复用,逻辑负责代码多了不好阅读
组合API:以功能为单位组织代码结构,后续重用功能更加方便;总结、组合API的最大好处就是以功能为单位组织代码结构,有利于代码的复用

三. 生命周期的变化

创建前:beforeCreate -> 使用setup()

创建后:created -> 使用setup()

挂载前:beforeMount -> onBeforeMount

挂载后:mounted -> onMounted

更新前:beforeUpdate -> onBeforeUpdate

更新后:updated -> onUpdated

销毁前:beforeDestroy -> onBeforeUnmount

销毁后:destroyed -> onUnmounted

异常捕获:errorCaptured -> onErrorCaptured

被激活:onActivated 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行。

切换:onDeactivated 比如从 A 组件,切换到 B 组件,A 组件消失时执行

四. v-if和v-for的优先级

在vue2中v-for的优先级高于v-if,可以放在一起使用,但是不建议这么做,会带来性能上的浪费

在vue3中v-if的优先级高于v-for,一起使用会报错。可以通过在外部添加一个标签,将v-for移到外层

五. diff算法不同

vue2中的diff算法

遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom

缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。

特点:特别要提一下Vue的patch是即时的,并不是打包所有修改最后一起操作DOM,也就是在vue中 边记录变更新。(React则是将更新放入队列后集中处理)。

vue3中的diff算法

在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识。只比较patchFlags发生变化的节点,进行识图更新。而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接复用。

六. 响应式原理不同

vue2通过Object.definedProperty()的get()和set()来做数据劫持、结合和发布订阅者模式来实现,Object.definedProperty()会遍历每一个属性。

vue3通过proxy代理的方式实现。

proxy的优势:不需要像Object.definedProperty()的那样遍历每一个属性,有一定的性能提升proxy可以理解为在目标对象之前架设一层“拦截”,外界对该对象的访问都必须通过这一层拦截。这个拦截可以对外界的访问进行过滤和改写。当属性过多的时候利用Object.definedProperty()要通过遍历的方式监听每一个属性。利用proxy则不需要遍历,会自动监听所有属性,有利于性能的提升

七. 插槽方式不同

具名插槽使用方式不同:vue2使用slot='',vue3使用v-slot:''

作用域插槽使用方式不同:vue2中在父组件中使用slot-scope="data"从子组件获取数据,vue3中在父组件中使用 #data 或者 #default="{data}"获取

八. 样式穿透

vue2中:

 /deep/ .类名{}
::v-deep .类名{}

vue3中:

:deep (.类名{})
::v-deep(.类名{})