一、Vue3新特性
1. 新的内置组件
- Teleport:通过
Teleport组件,开发者可以将组件渲染到 DOM 树的任意位置,简化了管理复杂布局的操作。
以下是 Teleport 的使用示例:
<template>
<Teleport to="body">
<div>This will be teleported to the body</div>
</Teleport>
</template>
- Suspense:结合异步组件的使用,
Suspense允许开发者在等待异步操作完成之前显示占位符,使异步加载情况更加优雅。
以下是 Suspense 的使用示例:
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
2 Fragments
- Vue 2:每个组件必须有一个根节点,可能导致不必要的包裹标签。
- Vue 3:支持 Fragment,组件可以返回多个根节点,使得组件结构更加灵活。
<template>
<h1>Hello</h1>
<p>World!</p>
</template>
3 更好的 JSX 支持
Vue 3 中对 JSX 的支持更加完善,允许开发者使用更现代的语法来构建组件:
const MyComponent = {
render() {
return <div>Hello, JSX!</div>;
}
};
二、响应性系统的变化
1. Vue 2 的响应系统
在 Vue 2 中,响应性是通过 Object.defineProperty 实现的。每个数据属性都是通过 getter 和 setter 来管理的。
const Vue = {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
}
};
- 优点:简单易用,可以将对象的状态与视图同步。
- 缺点:
-
- 新增属性:无法检测到新增属性,必须使用
Vue.set()。 - 数组变更:对数组的方法(如
push,pop,shift,unshift,splice)只有特定的实现来支持事件侦听,其他操作则无法触发视图更新。
- 新增属性:无法检测到新增属性,必须使用
2. Vue 3 的响应系统
Vue 3 中使用了 Proxy 来实现响应性。Proxy 可以监听对对象的全部操作,包括属性的添加、删除等。
import { reactive } from 'vue';
const state = reactive({
count: 0
});
function increment() {
state.count++;
}
- 优点:
-
- 新增属性:可以直接添加新的属性,Vue 3 会自动反应。
- 全面响应性:对数组和对象的响应支持更全面。
示例比较
// Vue 2 示例
var vm = new Vue({
data: {
obj: {
prop1: 'value1'
}
}
});
vm.obj.prop2 = 'value2'; // 视图不会更新
Vue.set(vm.obj, 'prop2', 'value2'); // 视图会更新
// Vue 3 示例
import { reactive } from 'vue';
const state = reactive({
obj: {
prop1: 'value1'
}
});
state.obj.prop2 = 'value2'; // 视图会自动更新
三、API 的变更
1. Options API vs. Composition API
Options API(Vue 2)
在 Vue 2 中,组件的选项如 data, methods, computed 等按不同属性分开放置。这样的结构在小组件中效果显著,但在管理大型组件时,则可能造成逻辑分散。
// Vue 2 组件
export default {
data() {
return {
count: 0,
message: 'Hello Vue!'
};
},
methods: {
increment() {
this.count++;
}
},
computed: {
doubledCount() {
return this.count * 2;
}
}
};
Composition API(Vue 3)
Vue 3 的 Composition API 引入了 setup() 函数,允许逻辑以函数为单位组合,大大改善了代码的可维护性和重用性。
// Vue 3 组件
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const message = 'Hello Vue!';
const increment = () => {
count.value++;
};
const doubledCount = computed(() => count.value * 2);
return { count, increment, doubledCount, message };
}
};
示例比较
Vue 2 示例:
const app = new Vue({
el: '#app',
data: {
items: ['item1', 'item2'],
searchText: ''
},
computed: {
filteredItems() {
return this.items.filter(item => item.includes(this.searchText));
}
}
});
Vue 3 示例:
import { createApp, ref, computed } from 'vue';
const app = createApp({
setup() {
const items = ref(['item1', 'item2']);
const searchText = ref('');
const filteredItems = computed(() => {
return items.value.filter(item => item.includes(searchText.value));
});
return { items, searchText, filteredItems };
}
});
app.mount('#app');
四、性能改进
1. 渲染性能
Vue 3 在 Virtual DOM 的实现上进行了优化,包括更高效的节点更新机制和更轻量的渲染器。根据官方统计,Vue 3 的渲染性能大约比 Vue 2 提升了 50%。
2. 编译优化
Vue 3 引入了编译时的静态提升和优化,这使得未更改的部分能够被静态分析,减少运行时开销。这对于高频渲染的组件特别关键。
示例比较
// Vue 2
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
}).$mount('#app');
// Vue 3
const app = createApp(App);
app.mount('#app');
五、生命周期钩子的变化
Vue 3 中的生命周期钩子有了一些变化,特别是增加了与 Composition API 结合的钩子。新手机更灵活、更易于管理。
| 钩子名称 | Vue 2 | Vue 3 |
|---|---|---|
| 创建前 | beforeCreate | 不变:onBeforeMount |
| 创建 | created | 不变:onMounted |
| 挂载前 | beforeMount | 不变:onBeforeMount |
| 挂载 | mounted | 不变:onMounted |
| 更新前 | beforeUpdate | 不变:onBeforeUpdate |
| 更新 | updated | 不变:onUpdated |
| 销毁前 | beforeDestroy | onBeforeUnmount |
| 销毁 | destroyed | onUnmounted |
| 额外钩子 | 无 | onActivated、onDeactivated、onErrorCaptured |
六、TypeScript 支持
Vue 2 对 TypeScript 的支持并不完善,许多 API 的类型推断有限。开发者往往需要手动声明类型,使用上有障碍。
Vue 3 在设计初期便考虑了 TypeScript 的支持,使得所有 API 都具有良好的类型推断。这为 TypeScript 用户提供了更好的开发体验。