Vue 3 是 Vue 2 的全新升级版本,引入了诸多新的特性,并在性能、开发体验、响应式系统等多个方面进行了改进。以下是 Vue 2 和 Vue 3 的详细对比:
1. 生命周期钩子差异
Vue 3 保留了大部分 Vue 2 的生命周期钩子,但部分名称有所调整,以适应新的 API 结构。
Vue 2 | Vue 3 |
---|---|
beforeCreate |
取消,改为 setup
|
created |
取消,改为 setup
|
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestroy |
onBeforeUnmount |
destroyed |
onUnmounted |
对比总结: Vue 3 中的生命周期钩子与组合式 API 更紧密集成,使用更加灵活。
2 响应式
Vue 2 依赖于 Object.defineProperty
的响应式系统在处理大量数据时有一定的性能瓶颈。
- Vue 2 处理静态和动态模板之间没有显著优化。
Vue 2 响应式系统
- 使用
Object.defineProperty
实现响应式。 - 无法检测属性的添加、删除,必须使用
Vue.set()
和Vue.delete()
。 - 数组的响应式处理存在局限,不能检测数组的直接索引赋值(如
this.items[0] = newItem
),需使用数组变更方法(如push
、pop
等)。
// Vue 2 响应式无法检测到对象属性的添加
this.$set(this.someObject, 'newProperty', 'value');
Vue 3 响应式系统
- 使用
Proxy
代替Object.defineProperty
。 - 能够自动追踪对象的添加和删除操作,也能监听数组索引的直接赋值。
- 支持对嵌套对象的深度监听,不需要手动处理复杂的嵌套结构。
- Vue 3 通过 Proxy 提高了响应式系统的性能,并解决了 Vue 2 的响应式系统中无法检测属性添加和数组索引赋值的问题。
const state = reactive({ count: 0 });
state.newProperty = 'value'; // 自动响应
3. Composition API(组合式 API)
Vue 2 Options API
Vue 2 中的逻辑组织方式是通过 Options API,组件的逻辑会分散在 data
、methods
、computed
、watch
等部分。
export default {
data() {
return { count: 0 };
},
methods: {
increment() {
this.count++;
}
}
}
Vue 3 Composition API
Vue 3 引入了 Composition API,通过 setup
函数集中管理组件的逻辑。它提供了更好的逻辑复用能力、增强了代码的可读性,特别是在复杂业务逻辑下表现得更加出色。
- 优势:组合式 API 更适合大型项目,组件的功能可以按逻辑进行封装,避免逻辑的分散。
-
逻辑复用:可以将通用功能封装为
composable
,在多个组件间共享。
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
}
4. 性能优化
1.0 Virtual DOM 优化
- Vue 2 的 Virtual DOM 虽然能够实现高效的 DOM diff,但在一些复杂场景下,仍然有改进空间,尤其是大型项目中。
- Vue 3 通过 编译时的优化,更智能地分析模板并生成更轻量的渲染函数。这些优化包括静态提升、事件缓存等,减少了不必要的 DOM 更新。
对比总结: Vue 3 的 Virtual DOM 实现更智能,减少了更新成本,特别是在使用静态内容时效率更高。
5. Typescript 支持
Vue 2 对 TypeScript 的支持
Vue 2 对 TypeScript 的支持有限。虽然可以通过类组件的方式使用 TypeScript,但这在编写复杂项目时可能显得笨拙。
import Vue from 'vue';
import Component from 'vue-class-component';
@Component
export default class MyComponent extends Vue {
message: string = 'Hello Vue!';
}
Vue 3 对 TypeScript 的支持
Vue 3 从设计之初就考虑了对 TypeScript 的支持。组合式 API 与 TypeScript 的结合更加自然,使用 TypeScript 的类型推导可以获得更好的开发体验。
import { ref } from 'vue';
export default {
setup() {
const count = ref<number>(0);
return { count };
}
}
- Vue 3 支持更好的类型推导、类型检查,增强了 TypeScript 和 Vue 组件的集成。
6. Vue 3 新特性
5.1 Fragments
Vue 3 支持 Fragment,允许组件返回多个根节点,而不需要包裹在一个父元素中。
<template>
<div>Header</div>
<div>Content</div>
</template>
在 Vue 2 中,组件必须有一个根元素。如果需要多个元素,必须用 <div>
包裹,这会引入多余的 DOM 结构。而 Vue 3 通过 Fragment 解决了这个问题。
6.2 Teleport
Vue 3 提供了 Teleport,允许你将组件的渲染输出移动到 DOM 树的其他位置,而不受父组件的影响。常用于模态框、提示框等全局展示的内容。
<template>
<teleport to="body">
<div class="modal">Modal Content</div>
</teleport>
</template>
6.3 Suspense
Vue 3 支持 Suspense,用于处理异步组件的渲染逻辑。在异步数据加载时,可以显示一个占位符,等异步数据加载完成后再显示真正的内容。
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
7. Vue 2 到 Vue 3 的迁移
迁移策略
- Vue 3 保持了大部分 Vue 2 的向后兼容性,Vue 官方提供了 Vue 3 升级指南 以及迁移工具,帮助开发者平稳过渡。
- 对于大型 Vue 2 项目,可以通过 兼容构建,允许在逐步迁移的过程中同时使用 Vue 2 和 Vue 3 的语法。
不兼容的更改
-
Vue 3 删除了一些不推荐的 Vue 2 API,如
$on
、$off
、keyCode
修饰符等。 -
v-model
现在支持在多个绑定时使用不同的prop
和event
,而不再是固定的value
和input
。 -
在 Vue 3 中,
filters
已经被移除,建议使用 computed 或 methods 来替代。 -
Vue 2 使用很多全局 API,例如
Vue.mixin
、Vue.use
、Vue.component
等。 -
Vue 3 取消了部分全局 API,将它们重构为应用实例级别的方法,以支持更好的模块化设计和多个 Vue 应用实例共存。
// Vue 2
Vue.mixin({...});
Vue.use(plugin);
// Vue 3
const app = createApp(App);
app.mixin({...});
app.use(plugin);
对比总结: Vue 3 改变了全局 API 的用法,更加模块化,增强了灵活性,且支持多实例运行。
事件 API
-
Vue 2 允许组件内部通过
$on
、$off
、$emit
监听和触发事件。 -
Vue 3 移除了
$on
、$off
、$once
,更推荐使用组合式 API 来处理事件逻辑,同时可以直接在setup
中管理事件。
// Vue 2
this.$on('customEvent', handler);
// Vue 3
// 推荐使用组合式 API 和 `emit`
7.2 v-model
Vue 3 的 v-model
变得更加灵活,可以自定义 prop
和 event
:
<!-- Vue 2 v-model: 固定为 `value` 和 `input` -->
<Child v-model="data" />
<!-- Vue 3 v-model: 可以自定义绑定字段和事件 -->
<Child v-model:title="data" />
总结
特性 | Vue 2 | Vue 3 |
---|---|---|
响应式系统 | Object.defineProperty |
Proxy |
API 风格 | Options API | 组合式 API(更灵活,适合复用) |
性能优化 | 基础优化 | 静态提升、缓存事件处理、异步渲染 |
Typescript 支持 | 支持,但不友好 | 原生支持,类型推导更佳 |
新特性 | Fragment、Teleport、Suspense 不支持 | 支持 Fragment、Teleport、Suspense |
迁移与兼容 | Vue 2 旧项目不完全支持 Vue 3 特性 | Vue 3 提供兼容构建和迁移工具 |
自定义渲染器 | 基本支持 | 完全支持,适合跨平台渲染 |
Vue.prototype原型,Vue3中也有替代方案app.config.globalProperties
import { getCurrentInstance } from 'vue'
export default getCurrentInstance()?.appContext.config.globalProperties
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$request: typeof request
}
}