Vue3 全面介绍
Vue3(正式名称为 Vue.js 3)是 Vue.js 前端框架的第三个主要版本,于 2020 年 9 月正式发布。作为对 Vue2 的重大升级,Vue3 在核心架构、性能优化、开发体验等方面进行了全面重构,同时保持了 Vue 一贯的“渐进式框架”理念,让开发者可以根据需求逐步采用其新特性。
一、Vue3 的核心改进
1. 全新的响应式系统
Vue3 放弃了 Vue2 中基于 Object.defineProperty
的响应式实现,转而采用 Proxy
API,带来以下优势:
原生支持数组索引和长度的响应式变化,无需像 Vue2 那样重写数组方法(如 push
、splice
);
支持对象动态添加/删除属性的响应式监听,Vue2 中需通过 Vue.set
/this.$set
手动处理;
响应式系统更高效,仅在访问属性时建立依赖,而非递归遍历对象所有属性;
支持 Map
、Set
等原生集合类型的响应式。
示例:Vue3 中动态添加响应式属性
import { reactive } from 'vue' const state = reactive({ name: 'Vue3' }) // 动态添加属性,自动具备响应式 state.age = 5 console.log(state.age) // 5(视图会同步更新)
2. 组合式 API(Composition API)
组合式 API 是 Vue3 的核心特性之一,旨在解决 Vue2 选项式 API(Options API)在大型项目中的痛点:
选项式 API 中,逻辑分散在 data
、methods
、computed
等选项中,复杂组件的逻辑难以聚合和用;
组合式 API 允许将相关逻辑(如数据、方法、监听)封装在一个函数中,实现“按功能组织代码”,而非“按选项类型组织代码”;
支持在多个组件间复用复杂逻辑,无需依赖混入(Mixin),避免混入带来的命名冲突和逻辑来源不清晰问题。
示例:组合式 API 实现计数器逻辑
import { ref, computed, onMounted } from 'vue' export default {setup() {// 1. 定义响应式数据const count = ref(0)// 2. 定义计算属性const doubleCount = computed(() => count.value * 2)// 3. 定义方法const increment = () => {count.value++}// 4. 生命周期钩子onMounted(() => {console.log('组件挂载完成,初始 count 为', count.value)})// 5. 暴露给模板使用return { count, doubleCount, increment }} }
3. 更好的 TypeScript 支持
Vue3 从底层使用 TypeScript 重写,相比 Vue2(需通过声明文件兼容 TypeScript),提供了更完善的类型推导:
组合式 API 中的 ref
、reactive
等 API 可自动推导数据类型,减少手动定义类型的工作量;
组件的 props
、emits
选项支持精确的类型校验;
支持在模板中进行类型检查(需配合 Volar 编辑器插件),提前发现类型错误。
示例:TypeScript + 组合式 API 定义 props
import { defineProps } from 'vue' // 定义 props 并指定类型 const props = defineProps<{title: stringcount?: number // 可选属性isVisible: boolean }>() // 使用 props 时自动获得类型提示 console.log(props.title.length) // 无类型错误 console.log(props.count?.toFixed(2)) // 可选链语法安全使用
4. 性能优化
Vue3 在编译和运行时层面进行了多项优化,性能显著优于 Vue2:
编译优化:模板编译时生成更高效的渲染函数,减少虚拟 DOM 的对比次数(如静态节点提升、补丁标记优化);静态属性(如 class="btn"
)会被提取到渲染函数外部,避免每次渲染时重复创建;条件渲染(v-if
)和列表渲染(v-for
)的编译逻辑优化,减少不必要的 DOM 操作。
运行时优化:响应式系统基于 Proxy
,减少不必要的依赖追踪;虚拟 DOM 算法优化,对比时仅关注动态节点,提升更新效率;支持片段(Fragments),组件可返回多个根节点,无需额外包裹 div
,减少 DOM 层级。
5. 内置组件与 API 调整
Vue3 对部分内置组件和 API 进行了调整,增强功能或简化使用:
特性 | Vue2 情况 | Vue3 改进 |
---|---|---|
片段(Fragments) | 组件必须有唯一根节点,需用 div 包裹 | 支持多根节点,无需包裹,编译时自动处理 |
v-model | 语法复杂,需配合 sync 修饰符实现双向绑定 | 简化语法,支持多个 v-model ,可自定义绑定属性和事件 |
Teleport | 无内置组件,需通过第三方库实现“组件内容挂载到指定 DOM 位置” | 内置 <Teleport> 组件,轻松实现弹窗、下拉菜单等场景 |
Suspense | 无内置支持,异步组件加载状态需手动处理 | 内置 <Suspense> 组件,统一管理异步组件的加载、错误状态 |
生命周期钩子 | 选项式 API(如 mounted 、updated ) | 组合式 API 中提供独立函数(如 onMounted 、onUpdated ),更灵活 |
二、Vue3 的两种组件写法
Vue3 支持两种组件开发方式,开发者可根据项目需求和团队习惯选择:
1. 选项式 API(Options API)
与 Vue2 的写法兼容,适合简单组件或习惯选项式开发的开发者。Vue3 对选项式 API 进行了部分兼容优化,确保现有 Vue2 项目可平滑迁移。
2. 单文件组件(SFC)+ 组合式 API
Vue3 推荐的写法,结合单文件组件(.vue 文件)和组合式 API,适合复杂组件和大型项目。Vue3 还支持 <script setup>
语法糖,进一步简化组合式 API 的代码:
无需手动导出组件(export default
);
无需在 setup()
函数中返回数据和方法,直接定义即可在模板中使用;
支持自动导入 ref
、computed
等 API(需配合构建工具配置)。
三、Vue3 的生态系统
Vue3 发布后,其官方生态工具也已同步升级,确保开发体验的一致性:
1. 构建工具:Vite
Vite 是 Vue 作者尤雨溪开发的新一代构建工具,相比 Webpack,具有以下优势:
开发环境启动速度极快(基于 ES 模块原生支持,无需打包);
热更新(HMR)响应迅速,修改代码后立即生效;
默认支持 Vue3、TypeScript、JSX 等,零配置即可使用;
生产环境基于 Rollup 打包,体积小、性能优。
创建 Vue3 + Vite 项目的命令:
# 使用 npm npm create vite@latest my-vue3-project -- --template vue # 进入项目目录并安装依赖 cd my-vue3-project npm install # 启动开发服务器 npm run dev
2. 路由:Vue Router 4
Vue Router 4 是 Vue3 的官方路由插件,与 Vue3 深度兼容,主要改进:
支持组合式 API,提供 useRouter
、useRoute
等 Hook,方便在 setup 函数中使用路由;
支持路由参数的响应式监听,无需手动监听 $route
变化;
优化路由匹配算法,支持动态路由和嵌套路由的更灵活配置。
示例:Vue Router 4 在组合式 API 中的使用
import { useRouter, useRoute } from 'vue-router' export default {setup() {const router = useRouter()const route = useRoute()// 获取路由参数console.log(route.params.id)// 跳转路由const goToHome = () => {router.push('/home')}return { goToHome }} }
3. 状态管理:Pinia
Pinia 是 Vue3 官方推荐的状态管理库,替代了 Vue2 中的 Vuex,主要优势:
完全支持 TypeScript,类型推导更完善;
简化 API,无需 mutations
(Pinia 中直接通过 actions
修改状态,支持同步和异步);
支持组合式 API,可在 setup 函数中轻松使用;
体积更小,性能更优,支持多仓库(多个 Store)。
示例:创建 Pinia Store 并使用
// 1. 创建 Store(src/stores/counter.js) import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),actions: {increment() {this.count++},async incrementAsync() {await new Promise(resolve => setTimeout(resolve, 1000))this.count++}},getters: {doubleCount: (state) => state.count * 2} })// 2. 在组件中使用 import { useCounterStore } from '@/stores/counter' import { setup } from 'vue' export default {setup() {const counterStore = useCounterStore()return {count: counterStore.count,doubleCount: counterStore.doubleCount,increment: counterStore.increment,incrementAsync: counterStore.incrementAsync}