vue3 与 vue2 区别

136 阅读4分钟

本文旨在大致了解vue2和vue3的区别,方便日后的vue3学习,后续可能会将一些复杂的区别详细另写一些文章分析

通过本人理解转译编写,有疑问的可以查官网或者评论区提出:v3-migration.vuejs.org/zh/breaking…

响应式系统
  • vue2:
    • 使用Object.defineProperty()来进行数据劫持,实现响应式。
    • 这种方式在初始化时需要遍历对象的每个属性,为其添加gettersetter。例如,对于一个对象data = {count: 0},Vue 2 会对count属性进行数据劫持,当访问count属性时会触发getter,修改count属性时会触发setter,从而实现响应式更新
    • 存在问题:
      • 给对象新增属性可能无法及时更新到视图,比如:给data对象新增一个属性name,直接data.name = 'John'不会触发视图更新,需要使用Vue.set(data, 'name', 'John')
      • 给数组通过下标进行修改可能无法及时更新到视图,比如:给数组arr=[1,2,3],通过arr[2]进行修改数组内容,可能无法更新到视图,需要通过set方式修改数组
  • vue3:
    • 采用Proxy来实现响应式系统。Proxy可以代理整个对象,而不仅仅是对象的属性。
    • 它能通过依赖收集,捕获对象的更多操作,存储与对象相关的操作,如属性的读取、赋值、函数调用等。例如,对于一个响应式对象reactiveData,通过Proxy可以拦截reactiveData.count的访问和修改,也能拦截reactiveData.someMethod()的调用,当对象被修改时,相关的dom、属性、函数调用等会在依赖收集的数据中依次执行。
    • 对于新增或删除属性,响应式对象会自动更新,不需要像vue2一样通过set方式来修改数据
虚拟Dom优化
  • vue2:采用了双端比较算法。在更新视图时,会对新旧虚拟 DOM 树进行比较,虽然这个算法比较高效,但在某些复杂场景下,如频繁更新大量节点时,性能可能会受到影响
  • vue3:采用了更高效的静态标记技术。在编译阶段,会为模板中的动态节点添加标记,在更新时,根据这些标记可以更精准地更新变化的部分,减少不必要的 DOM 操作,从而提高性能。
组件系统
  • vue2:
    • 采用选项式API,将组件中逻辑划分到不同的选项,如:data、methods等,数据存放与data中,方法存放于methods中
    • 普通插槽和作用域插槽分开
  • vue3:
    • 采用组合式API,允许开发者使用函数组合的方式复用和组合多个状态,包含于setup(prop,context)语法糖中,集中处理组件的状态、计算属性、方法和生命周期钩子等,
    • 数据通过ref或者reactive创建,不需要存放到data,
    • 通过props获取父组件传递的属性,
    • 通过context获取上下文对象包括attrs、slots、emit等,
    • 通过自定义useHooks,实现函数的复用
    • 异步组件需要通过将其包裹在 defineAsyncComponent
    • 普通插槽和作用域插槽合并,不能同时出现
指令
  • vue2:
    • v-if 优先级大于 v-for
    • 通过Vue直接绑定指令
    • 自定义指令生命周期bindinsertedupdatecomponentUpdatedunbind
    • v-model的prop默认名称value默认事件input
    • v-bind="$attrs" 才能让属性能够顺利地传递并应用到子组件内部的元素上
  • vue3:
    • v-for 优先级大于 v-if
    • 通过createApp函数将Vue暴露,创建app来绑定指令
    • 自定义指令生命周期created,beforeMount,mountedbeforeUpdate,updatedbeforeUnmount,unmounted
    • v-model的prop默认名称modelValue默认事件update:modelValue,同一个组件上可以多个v-model绑定
    • v-bind="$attrs" 没有这个也能默认自上而下传递属性,且context.attrs能读取到所有的属性
生命周期
  • vue2:beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestroydestroyed、如果插入keep-alive之后 ,activeteddeactivated
  • vue3:setuponBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmounted如果插入keep-alive之后 ,onActivatedonDeactivated
根节点
  • vue2:每个组件模板必须有且只有一个根节点
  • vue3:引入了片段(Fragment)的概念,每个组件模板可以没有根节点或者有多个根节点,
全局API应用
  • vue2:Vue.component 注册全局组件
  • vue3:调用 createApp 返回一个应用实例app,app.component注册全局组件,任何全局改变 Vue 行为的 API 现在都会移动到应用实例上
移除的APIs
  • $children
  • keyCodes 按键事件api
  • $on$off 和 $once事件api
  • filters过滤器
  • inline-template内联样式模板
  • propsData