基础语法
<script setup>是Vue3.2正式支持的一个语法糖,在<script setup>中的代码就像是在setup()函数中一样,所有顶级变量、函数、导入的组件都会暴露给模板使用(不用return)
使用方法十分简单,在<script>标签上添加setup属性即可:
<template>
<button @click="handleClick">
</template>
<script setup>
function handleClick() {
console.log("message in script setup")
}
</script>
传统的<script>只会在组件第一次被导入时执行,而<script setup>会在每一个组件实例被创建时执行
响应式
和传统的<script>一样,创建响应式变量,你需要使用Reactivity API,但你不再需要手动return
<template>
<button @click="count++">{{ count }}</button>
</template>
<script setup>
import { ref } from "vue"
const count = ref(0)
</script>
组件
导入的组件可以直接使用,你可以把组件名想象成一个变量:
<template>
<my-comp />
<MyComp />
</template>
<script setup>
import MyComp from "./MyComp.vue"
</script>
在模板中引入组件时,无论你使用kebab-case还是PascalCase的方式写标签名都是可以运行的,不过vue推荐使用PascalCase的命名方式,因为这样可以帮助你更好的区分自定义组件
动态组件
因为组件是作为变量被引入的,所以我们可以使用使用:is动态绑定组件:
<template>
<component :is="MyComp">
</template>
<script setup>
import MyComp from "./MyComp.vue"
</script>
递归组件
MyComp.vue可以通过<MyComp />来引用自己
命名空间组件
从一个文件导入多个组件时,你可以使用类似<Foo.Bar />的方式来引用组件
defineProps 和 defineEmits
顾名思义,defineProps()和defineEmits()就是在<script setup>中实现props和emits的
defineProps()、defineEmits()这两个函数接受的值和props、emits接受的值相同
<template>
<button @click="handleClick">{{ props.text }}</button>
</template>
<script setup>
import { defineProps, defineEmits } from "vue"
// props
const props = defineProps({
text: String
})
// emits
const emit = defineEmits(["handleClick"])
function handleClick() { /*...*/ }
</script>
defineExpose
在传统的<script>中,我们可以通过ref实例的方法访问子组件,但是在<script setup>中我们不能这么使用了,<script setup>其实就等于一个闭包,里面的内容只有<template>模板可以访问
如果我们要通过ref来访问子组件内容,可以使用defineExpose手动向外部暴露内容
<script setup>
import { defineExpose } from "vue"
const count = 0
defineExpose({
a
})
</script>
useSlots 和 useAttrs
一般来说,你会在模板中直接通过$slots和$attrs来访问slots和attrs,不过当你需要在<script>中使用时,你可以通过useSlots和useAttrs来获取
<script setup>
import { useSlots, useAttrs } from "vue"
const slots = useSlots()
const attrs = useAttrs()
</script>
和<script>一起使用
当你需要一个普通的<script>时(比如声明组件的name),你可以在组件中同时声明<script>和<script setup>,但只能各声明一个:
<script>
export default({
name: "MyComp"
})
</script>
<script setup>
const title = "Title"
</script>
顶层await
<script setup>是默认声明async的,类似于async setup()的效果,你可以在<script setup>中直接使用await函数:
<script setup>
const res = await fetch("/api/getData")
</script>
TypeScript 独占特性
props/emit的类型声明
可以使用仅通过类型来声明defineProps和defineEmits:
<script lang="ts" setup>
import { defineProps, defineEmits } from "vue"
const props = defineProps<{
msg: string,
count?: number
}>()
const emit = defineEmits<{
(e: 'change', id: number): void
}>()
</script>
为props设置默认值
<script lang="ts" setup>
import { defineProps, withDefaults } from "vue"
interface Props {
msg?: string,
labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
msg: "Hello",
labels: () => ["one", "two"]
})
</script>