--
teleport可以指定元素渲染到某一元素下;
如:
<teleport to="body"> <div>父级teleport</div> </teleport>
emits自定义事件
emits: ['inFocus', 'submit'] // 会覆盖原生事件 emits: { // 没有验证 click: null, // 验证 submit 事件 submit: ({ email, password }) => { if (email && password) { return true } else { console.warn('Invalid submit event payload!') return false } } }
v-module可以绑定多个值
<user-name v-model:first-name="firstName" v-model:last-name="lastName" ></user-name>
自定义v-model修饰符:
<div id="app"> <my-component v-model.capitalize="myText"></my-component> {{ myText }} </div> app.component('my-component', { props: { modelValue: String, modelModifiers: { default: () => ({}) } }, emits: ['update:modelValue'], methods: { emitValue(e) { let value = e.target.value if (this.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1) } this.$emit('update:modelValue', value) } }, template: `<input type="text" :value="modelValue" @input="emitValue">` })
<script setup>语法糖
声明的方法、变量、组件 可以直接在模板中使用;不用显示return出来
动态组件:
<script setup> import Foo from './Foo.vue' import Bar from './Bar.vue' </script> <template> <component :is="Foo" /> <component :is="someCondition ? Foo : Bar" /> </template>
递归组件、组件别名
例如:名为 FooBar.vue
的组件可以在其模板中用 <FooBar/>
引用它自己。
为了避免组件名和变量冲突,可以使用组件别名
import { FooBar as FooBarChild } from './components'
命名空间组件(引入多个组件时非常方便):
<script setup> import * as Form from './form-components' </script> <template> <Form.Input> <Form.Label>label</Form.Label> </Form.Input> </template>
使用自定义指令:
这里有一个需要注意的限制:必须以 vNameOfDirective
的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。
<script setup> const vMyDirective = { beforeMount: (el) => { // 在元素上做些操作 } } </script> <template> <h1 v-my-directive>This is a Heading</h1> </template>
<script setup> // 导入的指令同样能够工作,并且能够通过重命名来使其符合命名规范 import { myDirective as vMyDirective } from './MyDirective.js' </script>
defineProps
和 defineEmits
在 <script setup>
中必须使用 defineProps
和 defineEmits
API 来声明 props
和 emits
,它们具备完整的类型推断并且在 <script setup>
中是直接可用的:
<script setup> const props = defineProps({ foo: String }) const emit = defineEmits(['change', 'delete']) // setup code </script>
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>
useSlots
和 useAttrs
是真实的运行时函数,它会返回与 setupContext.slots
和 setupContext.attrs
等价的值,同样也能在普通的组合式 API 中使用
与普通的 <script>
一起使用
...
顶层 await
<script setup>
中可以使用顶层 await
。结果代码会被编译成 async setup()
:
<script setup> const post = await fetch(`/api/post/1`).then(r => r.json()) </script>
--