Tree-Shaking

支持了 tree-shaking (剪枝):像修剪树叶一样把不需要的东西给修剪掉,使 Vue3 的体积更小。

需要的模块才会打入到包里,优化后的 Vue3.0 的打包体积只有原来的一半(13kb)。哪怕把所有的功能都引入进来也只有23kb,依然比 Vue2.x 更小。像 keep-alive 、 transition 甚至 v-for 等功能都可以按需引入。

Teleport

一些类似 Modal 、 Dialog 、 Select 、 DropDwon 之类的组件,默认会把dom渲染到它所在的父节点上,但是实际上,类似这样的组件,我们是希望将其渲染到根节点上的,所以这时候,Teleport的出现,就为我们解决了这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
<teleport to="#root">
<div>A</div>
</teleport>
<teleport to="#root">
<div>B</div>
</teleport>

<!-- result-->
<div id="root">
<div>A</div>
<div>B</div>
</div>

Fragments

vue2.x中,由于不支持根节点,所以我们会将所有的组件包裹在一个div中,如下所示:

1
2
3
4
5
6
7
8
<!-- Layout.vue -->
<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>

这么做就会导致我们的页面额外多出来一级dom节点,3.0为了解决这个问题,引入了新的特性Fragement:

1
2
3
4
5
6
<!-- Layout.vue -->
<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>

代码简介命了很多,而且少了一层节点,diff的速度理所应当的会提升,但是,这么做,会有一个问题,就是attribute不会自动绑定到根节点的attribute中了,需要我们显示定义attribute应该分布在哪里

Component Custom Events

  • 事件名

与组件和 prop 一样,事件名提供了自动的大小写转换。如果用驼峰命名的子组件中触发一个事件,可以在父组件中添加一个 kebab-case (短横线分隔命名) 的监听器。

1
2
3
<my-component @my-evnet="doSomething"></my-component>

this.$emit('myEvent');
  • 定义emits

可以通过 emits 选项在组件上定义已发出的事件。

1
2
3
export default MyComponent{
emits: ['inFocus', 'submit']
}

和props一样,现在emits也支持验证了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default MyComponent{
emits: {
// 没有验证
click: null,

// 验证submit 事件
submit: ({ email, password }) => {
if (email && password) {
return true
} else {
console.warn('Invalid submit event payload!')
return false
}
}
},
methods: {
submitForm(email, password) {
this.$emit('submit', { email, password })
}
}
}
  • v-model

v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件

1
2
// MyComponent.vue
<input type="text" :value="title" @input="$emit('update:title',$event.target.value)" />
1
2
3
4
5
6
7
// MyComponent.vue
export default MyComponent{
props: {
title: String
},
emits: ['update:title'],
}
1
2
// App.vue
<my-component v-model:title="bookTitle"></my-component>

同时,现在v-model支持多个绑定了

1
2
3
4
5
// App.vue
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
1
2
3
4
5
6
7
8
9
// MyComponent.vue
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)" />
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)" />
1
2
3
4
5
6
7
8
// MyComponent.vue
export default {
props: {
firstName: String,
lastName: String
},
emits: ['update:firstName', 'update:lastName'],
}

Better TypeScript Support

更好的类型推导,使得Vue3对TypeScript支持的更好

Custom Render API

支持创建自定义渲染器,可以更好的支持Weex、Vue Native、小程序等