本文旨在大致了解vue2和vue3的区别,方便日后的vue3学习,后续可能会将一些复杂的区别详细另写一些文章分析
通过本人理解转译编写,有疑问的可以查官网或者评论区提出:v3-migration.vuejs.org/zh/breaking…
响应式系统
- vue2:
- 使用
Object.defineProperty()来进行数据劫持,实现响应式。 - 这种方式在初始化时需要遍历对象的每个属性,为其添加
getter和setter。例如,对于一个对象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直接绑定指令
- 自定义指令生命周期
bind、inserted、update、componentUpdated、unbind - v-model的prop默认名称
value默认事件input - v-bind="$attrs" 才能让属性能够顺利地传递并应用到子组件内部的元素上
- vue3:
- v-for 优先级大于 v-if
- 通过createApp函数将Vue暴露,创建app来绑定指令
- 自定义指令生命周期
created,beforeMount,mounted,beforeUpdate,updated,beforeUnmount,unmounted - v-model的prop默认名称
modelValue默认事件update:modelValue,同一个组件上可以多个v-model绑定 - v-bind="$attrs" 没有这个也能默认自上而下传递属性,且context.attrs能读取到所有的属性
生命周期
- vue2:
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed、如果插入keep-alive之后 ,activeted、deactivated - vue3:
setup、onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted如果插入keep-alive之后 ,onActivated、onDeactivated
根节点
- vue2:每个组件模板必须有且只有一个根节点
- vue3:引入了片段(
Fragment)的概念,每个组件模板可以没有根节点或者有多个根节点,
全局API应用
- vue2:Vue.component 注册全局组件
- vue3:调用
createApp返回一个应用实例app,app.component注册全局组件,任何全局改变 Vue 行为的 API 现在都会移动到应用实例上
移除的APIs
$childrenkeyCodes按键事件api$on,$off和$once事件apifilters过滤器inline-template内联样式模板propsData