Vue 3与Vue 2的核心差异对比
Vue 3新特性概述
Vue 3作为Vue.js框架的重大版本更新,带来了诸多革命性的变化。本文将系统性地介绍Vue 3相对于Vue 2的主要改进点。
1. 性能优化
- 打包体积缩减约41%
- 首次渲染速度提升55%,更新渲染提升133%
- 内存占用降低54%
2. 源码层面的改进
Vue 3采用Proxy替代Object.defineProperty来实现响应式系统,解决了Vue 2中无法检测数组索引变化的问题。同时重写了虚拟DOM实现,增加了Tree-Shaking支持,使得最终打包的代码更加精简。
3. TypeScript原生支持
Vue 3从架构层面支持TypeScript,提供了完整的类型定义文件,使开发者能够更好地享受静态类型检查带来的开发体验。
4. 新增特性
- Composition API(组合式API)
- setup配置项
- ref与reactive响应式API
- watch与watchEffect监听API
- 新增生命周期钩子函数
- 废弃keyCode支持,改用v-on修饰符
创建Vue 3项目
使用Vue CLI脚手架
执行以下命令创建项目:
vue create my-vue3-project
在项目创建过程中选择Vue 3版本即可。创建完成后,项目结构与Vue 2类似,主要差异体现在入口文件main.js的写法:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App)
.use(store)
.use(router)
.mount('#app')
采用链式调用方式注册插件并挂载应用实例。
使用Vite构建工具
Vite是新一代前端构建工具,特点是启动迅速、热更新即时。
安装命令:
npm init vue@latest
执行后可根据需求选择是否集成Vue Router、Pinia状态管理库、TypeScript支持等模块。
组合式API详解
Vue 3保留了Vue 2的配置式API,同时引入了更灵活的组合式API。在Vue 2的组件写法中,data、methods、computed等选项按照功能类型分类组织,当组件逻辑复杂时,相关功能的代码可能被拆分到不同位置。
组合式API允许开发者按照功能而非数据类型来组织代码,使得关联紧密的逻辑能够集中管理。
setup函数
setup是Vue 3新增的组件配置选项,作为组合式API的入口:
<template>
<div class="container">
<p>{{ username }}</p>
<p>{{ userInfo.age }} <button @click="incrementAge">+1</button></p>
<p>{{ userInfo.gender }}</p>
</div>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
export default {
name: 'UserProfile',
setup() {
// 非响应式数据,只渲染一次
const staticData = 'initial'
// ref创建响应式数据,支持所有类型
const username = ref('developer')
// reactive创建响应式对象,仅支持对象和数组
const userInfo = reactive({
age: 25,
gender: 'male'
})
// 定义方法
const incrementAge = () => {
userInfo.age.value++
}
// setup中定义的变量需返回才能在模板中使用
return {
staticData,
username,
...toRefs(userInfo),
incrementAge
}
}
}
</script>
setup函数整合了多种数据定义方式:
- 普通变量:不具有响应式特性,渲染一次后不再更新
- ref():创建响应式数据,支持基础类型和引用类型
- reactive():创建响应式对象,处理数组和对象类型
- toRefs():将响应式对象的每个属性转换为独立的ref
methods不再单独定义,可在setup内紧邻相关数据编写,使功能划分更清晰。
setup语法糖
通过script标签的setup属性可进一步简化代码:
<script setup lang="js">
import { ref, reactive } from 'vue'
const staticData = 'hello'
const username = ref('developer')
const userInfo = reactive({
age: 25,
gender: 'male'
})
const incrementAge = () => {
userInfo.age++
}
</script>
使用setup属性后,无需手动返回变量和方法,Vue 3会自动处理。lang属性可指定脚本语言,默认为项目配置的语言。
计算属性与监听器
计算属性
计算属性本质是带有缓存的方法:
import { computed } from 'vue'
const fullName = computed(() => {
return person.firstName + person.lastName
})
仅当依赖数据变化时才会重新计算。
计算属性的getter和setter:
import { computed, reactive } from 'vue'
const person = reactive({
firstName: 'Zhang',
lastName: 'San'
})
const fullName = computed({
get() {
return person.firstName + person.lastName
},
set(value) {
person.firstName = value.slice(0, 1)
person.lastName = value.slice(1)
}
})
实际应用:双向绑定用户输入的姓名,自动拆分姓和名。
监听器
watch用于监听特定数据变化并执行回调:
import { ref, watch, watchEffect } from 'vue'
const count = ref(0)
// 监听单个ref
watch(count, (newValue, oldValue) => {
console.log(`count变化: ${oldValue} -> ${newValue}`)
})
// 监听多个数据源
watch(
[count, otherRef],
([newCount, newOther], [oldCount, oldOther]) => {
console.log('数据变化了')
}
)
// watchEffect自动收集依赖
watchEffect(() => {
console.log(count.value)
})
watch需要明确指定监听目标,而watchEffect会自动收集回调函数中使用的响应式数据。
生命周期钩子对比
Vue 2到Vue 3的生命周期钩子名称变化:
| Vue 2 | Vue 3 |
|---|---|
| beforeCreate | setup() |
| created | setup() |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeDestroy | onBeforeUnmount |
| destroyed | onUnmounted |
在setup函数中使用生命周期钩子:
import { onMounted, onUnmounted } from 'vue'
setup() {
onMounted(() => {
console.log('组件已挂载')
})
onUnmounted(() => {
console.log('组件已卸载')
})
return {}
}
注意:beforeCreate和created在执行setup时已自动调用,无需显式导入。
setup语法糖中的生命周期
<script setup>
import { onMounted, onUpdated } from 'vue'
import axios from 'axios'
// 组件挂载时获取数据
onMounted(async () => {
const response = await axios.get('/api/data')
console.log(response.data)
})
// 数据更新后执行
onUpdated(() => {
console.log('组件已更新')
})
</script>
在setup语法糖中可以直接使用生命周期钩子,无需导入组件,import语句即注册组件。

