Vue2和Vue3的区别

1 组件优化

1 Fragment(多根组件)

  • Vue2 限制:组件模板必须单根节点,导致冗余包裹元素。
  • Vue3 改进:支持多根节点,减少 DOM 层级。

2 Teleport(传送门)

  • 功能:将组件渲染到 DOM或者是vue实例 任意位置(如全局弹窗)。
  • 场景:解决样式隔离或 DOM 嵌套限制问题。

需要注意的是,虽然 DOM 插头被传送到另一个地方,但它的父组件仍然是当前组件,这一点必须牢记,否则会导致样式、交互等问题。

Teleport 组件不仅支持具体的 id/选择器,还可以为to属性绑定一个 Vue 组件实例,比如:

xml 复制代码
<template>
  <teleport :to="dialogRef">
    <div>这里是瞬移到Dialog组件里的组件</div>
  </teleport>
  <Dialog ref="dialogRef"></Dialog>
</template>

总之,Teleport 组件是 Vue3 中新增的一个非常有用的组件,可以方便地实现一些弹出框、提示框等组件的功能,提高了开发效率。

3 Suspense(异步组件)

  • 功能:优雅处理异步组件加载状态,defalut插槽存放加载后内容,fallback插槽存放加载中的过渡内容。
  • 场景:数据请求、动态导入组件时的加载中/错误状态。

2 TS支持

3 保留原来的Options API,新增Composition API

提升了逻辑复用;代码组织;函数式写法更适合ts。

其中vue3新增了reactive函数和ref函数

  • reactive函数定义复杂数据类型的响应式数据,在js和模板中可直接使用
  • ref函数定义所有数据类型的响应式数据,在js中要.value来调用,模板中直接使用

遵循:尽量使用 ref 函数支持所有场景,确定字段的对象使用 reactive 可以省去.value

  • toRef:用于将某个对象的某个属性转换为响应式引用
  • toRefs:用于将某个响应式对象的所有属性转换为响应式引用
js 复制代码
import { reactive, toRef } from 'vue';

const state = reactive({ count: 0 });
const countRef = toRef(state, 'count');
console.log(countRef.value); // 0
js 复制代码
import { reactive, toRefs } from 'vue';

const state = reactive({ count: 0, name: 'Vue' });
const { count, name } = toRefs(state);
console.log(count.value); // 0
console.log(name.value); // Vue

拓展点:

  • watch:可监听单个或多个源,有明确监听目标的优先使用watch进行精确监听,写法:watch(source, callback, options?)
  • watchEffect:立即执行fn函数,自动追踪所有访问的响应式属性,无旧值处理逻辑

watch:

js 复制代码
// 监听单个ref
const count = ref(0)
watch(count, (newVal, oldVal) => {
  console.log(`Count changed from ${oldVal} to ${newVal}`)
})

// 监听getter函数
watch(
  () => state.user.age,
  (age) => console.log('Age updated:', age)
)

// 监听多个源
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
  // 处理变化逻辑
})

watchEffect:

js 复制代码
const stop = watchEffect((onCleanup) => {
  console.log('Count:', count.value)
  
  onCleanup(() => {
    console.log('Cleanup previous effect')
  })
})

// 停止监听
stop()

4 生命周期变化

阶段 组合式 API 钩子 选项式 API 钩子 调用时机说明
创建阶段 setup() beforeCreate/created 组合式 API 中 setup() 替代了 Vue 2 的这两个钩子,统一处理初始化逻辑
挂载阶段 onBeforeMount beforeMount 模板编译完成但未挂载到 DOM
onMounted mounted DOM 挂载完成,可安全操作 DOM 元素
更新阶段 onBeforeUpdate beforeUpdate 数据变化后,虚拟 DOM 重新渲染前触发
onUpdated updated 虚拟 DOM 重新渲染并应用补丁后触发
销毁阶段 onBeforeUnmount beforeUnmount 实例销毁前(Vue 2 的 beforeDestroy 更名,语义更清晰)
onUnmounted unmounted 实例销毁后(Vue 2 的 destroyed 更名)

关键说明:

  1. ‌命名变化:Vue 3 钩子名称更语义化(如 unmount 替代 destroy),组合式 API 需添加 on 前缀。
  2. setup() 整合:替代 Vue 2 的 beforeCreatecreated,集中处理响应式数据、方法等初始化逻辑。
  3. ‌选项式 API 兼容:Vue 3 仍支持选项式写法(如 mounted),但推荐使用组合式 API。

setup函数是组合式API的入口函数,默认导出配置选项,setup函数声明,返回模板需要数据与函数。

  • setup 函数是 Vue3 特有的选项,作为组合式API的起点
  • 从组件生命周期看,它在 beforeCreate 之前执行
  • 函数中 this 不是组件实例,是 undefined
  • 如果数据或者函数在模板中使用,需要在 setup 返回
  • 今后在vue3的项目中几乎用不到 this , 所有的东西通过函数获取。

5 底层响应式原理不同

Vue2使用的是Object.defineProperty()来劫持各个属性的setter/getter,在数据发生变化的时候通知订阅者更新视图。

缺点:

  • 无法检测到对象的属性添加和删除
  • 无法检测到数组的内部变化,因此Vue2通过重写数组方法来实现数组的响应式
  • 需要遍历整个对象,如果对象嵌套过深,需要递归遍历,性能会下降

Vue3使用的是Proxy来劫持整个对象,从而实现响应式。Proxy可以直接监听对象和数组的变化,不需要遍历整个对象,性能会更好。

优点:

  • 可以监听到对象和数组的变化
  • 可以监听到对象属性的添加和删除
  • 浅层监听,只有当对象的深层属性被使用到时才会递归遍历监听。减少了性能开销。

vue3的proxy优势

  • proxy性能整体上优于Object.defineProperty
  • vue3支持更多数据类型的劫持(vue2只支持Object、Array;vue3支持Object、Array、Map、WeakMap、Set、WeakSet)
  • vue3支持更多时机来进行依赖收集和触发通知(vue2只在get时进行依赖收集,vue3在get/has/iterate时进行依赖收集;vue2只在set时触发通知,vue3在set/add/delete/clear时触发通知),所以vue2中的响应式缺陷vue3可以实现
  • vue3做到了"精准数据"的数据劫持(vue2会把整个data进行递归数据劫持,而vue3只有在用到某个对象时,才进行数据劫持,所以响应式更快并且占内存更小)
  • vue3的依赖收集器更容易维护(vue3监听和操作的是原生数组;vue2是通过重写的方法实现对数组的监控)

Vue3 的 Diff 优化策略

1.靶向更新(Targeted Updates)

  • 补丁标志(Patch Flags) 在编译阶段分析模板,为动态绑定的节点添加标记(如 TEXT、CLASS、PROPS),标记其动态部分类型。 效果:Diff 时只需检查标记的动态属性,跳过静态内容。

  • 静态提升(Static Hoisting)

    将静态节点(无动态绑定)提取到渲染函数外部,避免重复创建 VNode。

    效果:减少内存占用和 Diff 时的比对次数。

  1. 块树(Block Tree)与动态锚点

块(Block) 将模板中的动态节点(含 v-if、v-for 或动态插槽)包裹为「块」,每个块追踪其内部动态子节点。

动态锚点 在块内记录动态节点的位置,更新时直接定位到动态部分,跳过静态结构。

效果:Diff 范围从整棵树缩小到块内动态节点,复杂度从 O(n) 降低到 O(动态节点数)。

  1. 最长递增子序列(LIS)优化列表更新

问题场景:当列表元素顺序变化时,Vue2 的双端比较可能导致多次 DOM 移动。

Vue3 解决方案: 在确定新旧子节点映射后,使用 最长递增子序列算法 找到最少的 DOM 移动路径。

示例: 新旧子节点索引序列为 [2, 3, 1, 4] → LIS 为 [2, 3, 4],只需移动节点 1 到正确位置。

效果:最小化 DOM 移动次数,提升列表渲染性能。

6 vue3 hooks

Hooks是一种特殊的函数,它可以让你在函数组件中使用状态和其他Vue特性。Vue3中的Hooks通常具有以下特征:

  • 以"use"作为函数名称前缀
  • 返回一个包含响应式数据或方法的对象
  • 可以使用其他Hooks
  • 遵循组合式函数的设计模式

与 Vue2 Mixins 的对比

对比项 Vue3 Hooks Vue2 Mixins
逻辑隔离 闭包封装,状态独立 共享上下文,易命名冲突
代码组织 函数式,逻辑集中 分散在多个选项(data、methods)
调试友好性 状态来源清晰,易追踪 数据来源隐式,调试困难

使用案例: blog.csdn.net/BillKu/arti...

7 createApp 是 Vue3 应用创建的入口函数,用于生成 Vue 应用实例,是 Vue3 官方推荐的应用初始化方式

Vue3 的实现了多实例隔离机制,在Vue2(new Vue())中只能有一个全局唯一的应用实例,只能挂载到一个根元素,并且全局共享配置。但是在vue3(createApp())中允许多实例共存 ,每个实例独立配置(组件/插件/指令)并且每个实例可挂载到不同容器 ‌。

pinia

vuex与pinia区别:

  1. ‌API设计与使用方式‌:
  • ‌Vuex‌: 需要定义state、mutations、actions和getters四个核心概念: 同步状态修改必须通过mutations提交。 异步操作需在actions中通过commit触发mutations‌‌
  • ‌Pinia‌: 简化API流程,直接通过actions同步/异步修改state,无需mutations,代码量减少40%。‌‌ ‌
  1. TypeScript支持‌:
  • ‌Vuex‌: 类型系统复杂,需手动定义类型装饰器,在大型项目中维护成本较高。‌‌
  • ‌Pinia‌: 原生支持类型推断,可直接通过this访问状态并自动推导类型,类型安全性和开发效率更高。‌‌
  1. ‌模块化管理‌:
  • ‌Vuex‌: 采用命名空间模块化设计,嵌套结构易导致代码复杂度增加,模块间依赖管理困难。‌‌
  • ‌Pinia‌: 每个store独立存在,支持扁平化组合式模块管理,通过defineStore实现天然代码分割。‌‌

‌注意:storeToRefs ‌是 Pinia 提供的一个工具函数,用于在 Vue 3 的组合式API中解构Store的状态(state)或计算属性(getters)时保持响应性。

js 复制代码
import { storeToRefs } from 'pinia'
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const { name, age, isAdult } = storeToRefs(userStore)

详细案例:juejin.cn/post/705743...

相关推荐
该换个名儿了6 分钟前
git多个commit合并成一个
前端·git
LaoZhangAI8 分钟前
2025最新OpenAI组织验证失败完全解决方案:8种有效方法彻底修复【实战指南】
前端·后端
siwangqishiq220 分钟前
Vulkan Tutorial 教程翻译(三) 绘制三角形 2.1 安装
前端
LaughingZhu21 分钟前
PH热榜 | 2025-06-05
前端·人工智能·经验分享·搜索引擎·产品运营
大模型真好玩21 分钟前
最强大模型评测工具EvalScope——模型好不好我自己说了算!
前端·人工智能·python
Dream耀37 分钟前
CSS选择器完全手册:精准控制网页样式的艺术
前端·css·html
wordbaby37 分钟前
React 19 亮点:让异步请求和数据变更也能用 Transition 管理!
前端·react.js
月亮慢慢圆38 分钟前
VUE3基础之Hooks
前端
我想说一句39 分钟前
CSS 基础知识小课堂:从“选择器”到“声明块”,带你玩转网页的时尚穿搭!
前端·javascript·面试