vue2 和 vue3 的区别

1,940 阅读4分钟

vue2 和 vue3 的区别

  1. vue2 vue3 响应式原理不同
  2. vue3 支持碎片,vue2 不支持
  3. vue2 是选项式 API,vue3 是组合式 API
  4. 生命周期不同
  5. v-if 和 v-for 的优先级不同
  6. diff 算法不同
  7. vue3 新增 Teleport 传送门组件

1. vue2 vue3 响应式原理不同

  • vue2 的双向数据绑定是利用 ES5 的一个 APIObject.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的
  • vue3 利用 Proxy 实现数据挟持,创建一个对象的代理,实现基本操作的拦截和自定义。本质上是通过拦截对象的内部方法的执行实现代理。Vue3 中提供了 reactive()和 ref()两个方法将目标数据变为响应式数据。

Object.defineProperty()存在的问题

  1. 只能拦截对象属性的 get 和 set 操作,无法拦截 delete、in、方法调用等操作。

  2. 一次只能对一个属性实现数据挟持,需要递归遍历所有属性进行挟持。

  3. 无法响应式处理新增属性和删除属性。需使用 this.set()设置新属性,使用this.set()设置新属性,使用 this.delete() 删除属性。

  4. 无法监听数组下标的变化。

  5. 对于数组而言,大部分操作都拦截不到,需要对 Array 原型支持的方法进行对应改写。

  6. 直接对原对象进行直接改写属性监听。

利用 Proxy 实现数据劫持的优势:

  1. 解决了使用 Object.defineProperty()继续数据劫持的缺点,完美监听任何方式导致的数据改变行为。

  2. 对于整个拦截对象直接进行挟持,无需遍历属性依次添加定义 get 和 set 属性。

  3. 对于原对象生成拦截对象,然后对拦截对象进行相应监听行为,确保原对象不变。

2. vue3 支持碎片,vue 不支持

vue3 中组件的 template 下可以包含多个根节点, vue2 中组件的 template 下只能包含一个根节点

3. vue2 是选项式 API,vue3 是组合式 API

vue2 选项式 api 在代码里分割了不同得属性:data,methods,computed 等,同一块业务逻辑会把数据和方法拆分到不同的代码块中,开发式需要不断上下滚动代码,开发很不方便。

vue3 组合式 api 能让相同的业务的数据方法写在同一块代码区域,这样代码会更加简便和整洁

4. 生命周期不同

vue2vue3
beforeCreate-
created-
boforeMountonBoforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
activatedonActivated
deActivatedonDeactivated

5. v-if 和 v-for 的优先级不同

vue2 v-for 优先于 v-if 生效,每次都要先渲染才会进行条件判断,会带来性能的浪费。最好不要把 v-if 和 v-for 同时用在一个元素上

vue3 v-if 优先于 v-for 生效,把 v-if 和 v-for 同时用在一个元素上 vue 中会给我们报警告

<div v-if="index == 1" v-for="(item,index) in arr" :key="index">{{item}}</div>

警告:属性“index”在渲染期间被访问,但未在实例上定义(v-if 先进行判断,但是这时候 v-for 还没有渲染,所以 index 是找不到的)

6. diff 算法不同

vue2 diff 算法就是进行虚拟节点对比,并返回一个 patch 对象,用来存储两个节点不同的地方,最后用 patch 记录的消息去局部更新 Dom。 diff 算法会比较每一个 vnode,而对于一些不参与更新的元素,进行比较是有点消耗性能的。

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

7. vue3 新增 Teleport 传送门组件

<Teleport to="body">
  需要传送到body下面的内容
</Teleport>

将 Teleport 组件标签内部的 dom 插入到 body 中 to 允许接收值: 期望接收一个 CSS 选择器字符串或者一个真实的 DOM 节点。