新特性
1. 组合Api
2. Teleport
设置组件挂在的body的位置
3. 片段
template内可以设置多个元素,不再局限于一个根节点
4. Emits 组件选项
-
Html attribute 名不区分大小写,浏览器会将所有大写字符解释为小写字符,故在dom模板使用时,驼峰需要使用横向-分割的等效值。 -
事件名 与组件和 prop 一样,事件名提供了自动的大小写转换。如果在子组件中触发一个以 camelCase (驼峰式命名) 命名的事件,你将可以在父组件中添加一个 kebab-case (短横线分隔命名) 的监听器。 javascript this.$emit('myEvent') html <my-component @my-event="doSomething"></my-component> -
定义自定义事件 可以在emits 选项在组件上定义发出的事件,当在 emits 选项中定义了原生事件 (如 click) 时,将使用组件中的事件替代原生事件侦听器。 -
v-model参数 组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件。我们可以通过向 v-model 传递参数来修改这些名称:
<my-component v-model:title="bookTitle"></my-component>
- 多个model参数
单个组件示例上可以创造多个v-model绑定,v-mode绑定的值将同步到prop - model修饰符,可以自定义
5. createRenderer 全局API 自定义渲染器
createRenderer 文档
6. 单文件组件 <script setup>
<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的 <script> 语法,它具有更多优势:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 TypeScript 声明 props 和抛出事件。
- 更好的运行时性能
其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理 - 更好的 IDE 类型推断性能
减少语言服务器从代码中抽离类型的工作 注:
-
setup 中的代码会在每次组件实例被创建时执行 -
顶层的绑定会暴露给模板。变量,函数声明,以及 import 引入的方法,组件, 都能在模板中直接使用 -
响应式(响应式api) -
动态组件使用动态的:is 来绑定 <script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>
<template>
<component :is="Foo" />
<component :is="someCondition ? Foo : Bar" />
</template>
-
递归组件 相比于import导入文档组件,优先级更低 -
命名空间组件 使用* 引入,在模板内可以使用带点的组件标记。 <script setup>
import * as Form from './form-components'
</script>
<template>
<Form.Input>
<Form.Label>label</Form.Label>
</Form.Input>
</template>
-
自定义指令 必须为vNameOfDirective 来命名本地自定义指令 例1:
<script setup>
const vMyDirective = {
beforeMount: (el) => {
}
}
</script>
<template>
<h1 v-my-directive>This is a Heading</h1>
</template>
例2:
<script setup>
import { myDirective as vMyDirective } from './MyDirective.js'
</script>
-
defineProps 和 defineEmits 在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits 。 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的范围。因此,传入的选项不能引用在 setup 范围中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块范围内。 -
defineExpose 使用 <script setup> 的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。为了在 <script setup> 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏。 <script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
-
useSlots 和 useAttrs 在 <script setup> 使用 slots 和 attrs 的情况应该是很罕见的,因为可以在模板中通过 $slots 和 $attrs 来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots 和useAttrs 两个辅助函数: <script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
-
与普通的 <script> 一起使用 普通的 <script> 在有这些需要的情况下或许会被使用到:
- 无法在
<script setup> 声明的选项,例如 inheritAttrs 或通过插件启用的自定义的选项。 - 声明命名导出。
- 运行副作用或者创建只需要执行一次的对象。
-
顶层 await 结果代码会被编译成 async setup() ,需要和Suspense 组合使用 <script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>
-
没有src的导入
7. 单文件组件状态驱动的 CSS 变量 (<style> 中的 v-bind)
单文件组件的 <style> 标签可以通过 v-bind 这一 CSS 函数将 CSS 的值关联到动态的组件状态上,这个语法同样也适用于 <script setup> ,且支持 JavaScript 表达式 (需要用引号包裹起来):
<style>
.text {
color: v-bind(color);
}
p {
color: v-bind('theme.color');
}
</style>
实际的值会被编译成 hash 的 CSS 自定义 property,CSS 本身仍然是静态的。自定义 property 会通过内联样式的方式应用到组件的根元素上,并且在源值变更的时候响应式更新
SFC <style scoped> 现在可以包含全局规则或只针对插槽内容的规则
<style scoped>
::v-deep(.foo) {}
:deep(.foo) {}
::v-slotted(.foo) {}
:slotted(.foo) {}
::v-global(.foo) {}
:global(.foo) {}
</style>
Suspense
|