从 Vue 2 到 Vue 3
Vue 3 是对 Vue 2 的一次重大更新,带来了许多改进和新特性。下面是几个Vue 3 与 Vue 2 之间的几个主要区别。
1.特性上的差异
1. 性能提升
Vue 3 在性能上做了大量优化,尤其是在渲染性能和内存管理方面。Vue 3 的虚拟 DOM 变得更加高效,它通过静态标记和优化的脏检查算法,显著提高了渲染性能。此外,Vue 3 引入了基于 Proxy 的响应式系统,相比 Vue 2 的 Object.defineProperty,性能得到了大幅提升。
2. Composition API
Vue 3 引入了 Composition API,这是与 Vue 2 最大的区别之一。Vue 2 采用的是 Options API,通过 data
、methods
、computed
等选项来组织组件。而在 Vue 3 中,Composition API 提供了一种新的方式来组织逻辑和状态,更多地强调函数式编程,使得代码更具灵活性和可复用性。
例如,Vue 3 中的 setup
函数是 Composition API 的核心,它是一个新的组件初始化函数,所有的逻辑和状态可以在 setup
函数中集中定义。
3. 更小的包体积
Vue 3 对框架进行了重构,使得最终的构建包体积更小。通过更加高效的 Tree Shaking,Vue 3 使得打包的体积更加精简,减少了未使用代码的打包。
4. 更好的 TypeScript 支持
Vue 3 对 TypeScript 的支持做了深入优化。Vue 3 的源码和 API 本身就是用 TypeScript 编写的,开发者在开发过程中能享受到更好的类型推导和检查功能,这使得 TypeScript 在 Vue 项目中的使用变得更加自然。
5. Suspense 和 Fragments
Vue 3 引入了 Suspense
组件和 Fragments
组件。
Suspense:允许我们在异步组件加载过程中进行界面上的占位显示,这是 React 中的一个概念,现在 Vue 3 也支持了类似的功能。
Fragments:Vue 3 允许一个组件返回多个根节点,这意味着组件不再需要有单一的根元素,使得组件结构更加灵活。
2.指令机制的差异
在 Vue 2 和 Vue 3 中,指令(Directives)机制有一些变化。虽然大多数 Vue 2 的指令和修饰符在 Vue 3 中依然有效,但也有一些关键的差异和变化。以下是 Vue 2 和 Vue 3 中指令相关的主要差异和改进。
在 Vue 3 中,指令(如 v-model
、v-bind
、v-on
)的基本功能保持不变,但 API 得到了优化,特别是在组件和自定义指令方面的改进。例如,Vue 3 改进了 v-model
的多重绑定支持,优化了指令的生命周期钩子,增加了更简洁和灵活的语法。同时,Vue 3 引入的 Composition API 为指令的使用和组织提供了更多的灵活性和可读性。
1. v-model
的差异
Vue 2:
v-model
用于实现双向数据绑定。它绑定到一个输入控件(如input
、textarea
、select
)的value
属性,自动处理input
事件来更新数据。html<input v-model="message">
Vue 3:
v-model
的语法发生了一些变化。默认情况下,v-model
仍然绑定到value
属性,但它现在支持 多个 v-model 和 自定义事件名。在 Vue 3 中,
v-model
可以接收自定义的modelValue
(作为 prop),而不再默认为value
。html<!-- 在 Vue 3 中,默认值是 'modelValue' --> <input v-model="message"> <!-- 对于自定义组件,可以通过指定 'modelValue' 属性来实现 v-model --> <MyComponent v-model="message"></MyComponent>
另外,Vue 3 允许给组件上的
v-model
使用多个绑定和自定义事件:html<MyComponent v-model:title="title" v-model:content="content"></MyComponent>
2. v-bind
的差异
Vue 2:
v-bind
用于动态绑定属性或类,语法为v-bind:属性="表达式"
,支持单个属性绑定或多个属性同时绑定。
Vue 3:
v-bind
的使用方式与 Vue 2 相同,但 Vue 3 在 Composition API 中引入了ref
、reactive
等新的响应式数据结构,结合这些新特性,v-bind
可以更加高效地与响应式数据配合使用。html<div v-bind="{ className, style }"></div>
3. v-for
的差异
Vue 2:
v-for
支持item in items
的形式来循环渲染数组或对象,必须指定key
来确保优化渲染。
Vue 3:
v-for
仍然与 Vue 2 类似,但 Vue 3 引入了v-for
对对象解构的支持,允许使用更多灵活的方式来循环对象。html<ul> <li v-for="(item, index) in items" :key="item.id">{{ item.name }}</li> </ul>
4. v-slot
的差异
Vue 2:
v-slot
用于命名插槽的绑定。例如:html<template v-slot:header> <h1>{{ title }}</h1> </template>
Vue 3:
Vue 3 中,
v-slot
的语法没有变化,但它允许v-slot
与多个插槽更加灵活地组合和使用。例如,你可以同时使用默认插槽和具名插槽,且v-slot
的简化语法得到广泛应用:html<MyComponent> <template #header> <h1>{{ title }}</h1> </template> </MyComponent>
5. v-on
的差异
Vue 2:
v-on
用于绑定事件监听器。可以通过.stop
、.prevent
等修饰符来控制事件行为。html<button v-on:click="handleClick">Click</button>
Vue 3:
v-on
的使用方式没有太大变化,唯一的变化是 Vue 3 对v-on
指令支持了更多的事件修饰符,例如.once
、.capture
、.stop
、.prevent
、.passive
。<button @click.stop="handleClick">Click</button>
6. 自定义指令的变化
Vue 2:
Vue 2 允许通过
Vue.directive
来全局注册自定义指令,也支持在组件中局部注册自定义指令。jsVue.directive('focus', { inserted(el) { el.focus(); } });
Vue 3:
在 Vue 3 中,指令的 API 经历了改动,特别是在
bind
和inserted
钩子方面。bind
和inserted
被合并为beforeMount
和mounted
,其他生命周期钩子也有所改变,整体变得更简洁。Vue 3 中的指令生命周期钩子:
beforeMount
: 替代bind
和inserted
。mounted
: 替代inserted
。
jsapp.directive('focus', { beforeMount(el) { el.focus(); } });