前言
Vue.js 是一个不断发展的,用于构建用户界面的渐进式框架。自首次发布以来,Vue.js 因其对开发人员友好的语法、易用性和完善的开发文档而越来越受欢迎,获得了许多开发人员的喜爱。
2020 年 9 月,Vue.js 第三版发布,2022 年 2 月成为新的默认版本。Vue 3 更小,更容易维护,并且有更多方便的功能。
Vue3的新特性
我们来看看在 Vue3 学习过程中,用到的一些新功能。
Teleport
之前称为 Portal,Teleport 允许我们决定可以在哪个父元素下放置一段 HTML 代码来呈现。Teleport 的主要优点是您可以将元素放置在 DOM 树中的任何位置,因此我们不需要嵌套组件或在某些情况下将代码拆分为两个组件。
它接受一个名为 to
的属性,我们可以在其中指定我们想要放置元素的位置,一个条件是目标元素应该在组件安装之前存在。
所以在 Vue 3 中,应该是这样的:
<teleport to="#app">
<div>Foo</div>
</teleport>
<teleport to="#app">
<div>Bar</div>
</teleport>
编译结果:
<div id="app">
<div>Foo</div>
<div>Bar</div>
</div>
demo:Teleport实现modal弹窗
过滤器从 Vue 3 中移除
不再支持过滤器,我们可以使用计算属性来替代。
Vue 2
<template>
<div id="app">
<span>{ { amount | usd } }</span>
</div>
</template>
<script>
export default {
data() {
return {
amount: 10
}
},
filters: {
usd(val) {
return val + '$'
}
}
}
</script>
Vue 3
<template>
<div id="app">
<span>{ { usd } }</span>
</div>
<template>
<script>
export default {
data() {
return {
amount: 10
}
},
computed: {
usd() {
return this.amount + '$'
}
}
}
</script>
demo: 汇率计算示例
实验性质的 Suspense 组件
Vue 3 允许我们使用 Suspense 组件执行延迟加载组件。
该 <Suspense>
组件允许我们在用户等待数据时提供一些备用内容,因此我们可以看到其他内容,例如加载中文本。
一个常见的异步组件示例:
<template>
<suspense>
<template #default>
<todo-list />
</template>
<template #fallback>
<div>
Loading...
</div>
</template>
</suspense>
</template>
<script>
export default {
components: {
TodoList: defineAsyncComponent(() => import('./TodoList.vue'))
}
}
</script>
<suspense>
组件有两个插槽。它们都只接收一个直接子节点。default
插槽里的节点会尽可能展示出来。如果不能,则展示 fallback
插槽里的节点。
demo: Suspense简单使用
重要的是,异步组件不需要作为
demo: 子组件加载异步组件
另一个触发 fallback
的方式是让后代组件从 setup
函数中返回一个 Promise。通常这是通过 async
实现的,而不是显式地返回一个 Promise:
demo: async setup组件
Fragment
在 2.x 中,由于不支持多根节点组件,当其被开发者意外地创建时会发出警告。结果是,为了修复这个问题,许多组件被包裹在了一个 <div>
中。
<!-- Layout.vue -->
<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>
在 3.x 中,组件可以包含多个根节点!但是,这要求开发者显式定义 attribute 应该分布在哪里。
<!-- Layout.vue -->
<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>
实验性质的 CSS 变量
CSS 变量允许我们在一个地方存储一个值,然后在我们的 CSS 代码的其他地方重用它,这是一种让代码更简洁的好方法。
在 Vue 3 中,单个文件组件中的 <style>
标签支持 v-bind()
函数,因此我们可以将组件状态中的值绑定到任何 CSS 属性,这允许我们动态地改变一些 CSS 属性的值。
<script setup>
import { ref } from 'vue'
const colors = ['red', 'blue', 'green']
const selColor = ref("")
</script>
<template>
<h1 class="txt">选择颜色改变文字</h1>
<select v-model="selColor">
<option value="">请选择</option>
<option v-for="(color, index) in colors" :value="color" :key="color">{{color}}</option>
</select>
</template>
<style scoped>
.txt {
color: v-bind(selColor);
}
</style>
demo: 样式V-BIND示例
单个文件组件 <style scoped>
更改
-
<style>
标签现在支持 v-bind 功能 -
我们可以使用
::v-deep()
或更短的版本:deep()
来代替现在不推荐使用的>>>
和/deep/
组合器。demo: v-deep示例
-
如果我们不想让带槽的组件同时受到父组件样式和子组件的作用域样式的影响,我们可以使用
::v-slotted()
或:slotted()
伪元素。
多个 v-models
在 Vue.js 中,我们使用 v-model
进行双向绑定。最普遍的使用方式是表单元素。在 Vue 2 中,我们只能在单个组件中使用一个 v-model
,但是 Vue 3 允许我们通过指定名称来将多个 v-model
传递给我们的组件,让我们看看它会是什么样子。
Vue 2
<template>
<div id="app">
<exampleForm v-model="person" />
</div>
</template>
<script>
export default {
data() {
return {
person: {
age: 20,
name: "Jan"
}
};
}
};
</script>
Vue 3
<template>
<div id="app">
<exampleForm v-model:age="person.age" v-model:name="person.name" />
</div>
</template>
<script>
export default {
data() {
return {
person: {
age: 20,
name: "Jan"
}
};
}
};
</script>
demo: v-models示例
生命周期命名修改
生命周期 destroyed
已重命名为 unmounted
。 beforeDestroy
更改为beforeUnmount
。
Options API (默认) | Composition API (setup钩子函数) |
---|---|
beforeCreate | Not needed |
created | Not needed |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
参考链接
What’s New in Vue 3? The Most Interesting New Features
vuejs中文网