Appearance
<script setup> 是 Vue 3 的推荐写法,它是组合式 API 的"语法糖"——把繁琐的样板代码省掉了,代码更简洁。
从"老写法"到"语法糖"
vue
<!-- ❌ 老写法(组合式 API 但不用语法糖) -->
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
function addOne() {
count.value++
}
return { count, addOne } // 必须手动 return 才能在模板中用
}
}
</script>
vue
<!-- ✅ 语法糖(<script setup>) -->
<script setup>
import { ref } from 'vue'
const count = ref(0)
function addOne() {
count.value++
}
// 不用 return!顶层的变量和函数自动暴露给模板
</script>
💡 Tip:"语法糖"是什么意思? 语法糖 = 写起来更甜的语法。功能没变,就是让你少写几行代码。<script setup> 做的事和老写法完全一样,只是帮你去掉了 export default、setup()、return 这些样板。
核心规则
用 <script setup> 后,记住这几点:
- 导入即注册 —
import组件后直接能用,无需components: {} - 顶层变量自动暴露 — 模板中直接使用,不用
return - 顶层的
await— 可以直接用const data = await fetch(...)(需要组件外层包<Suspense>)
defineProps — 接收父组件数据
vue
<script setup>
const props = defineProps<{
title: string
count?: number // ? 表示可选
}>()
// JS 中用 props.title 访问(不用 .value)
console.log(props.title)
</script>
<template>
<p>{{ title }}</p> <!-- 模板中可以解构,直接写 title -->
</template>
对比选项式 API:props: ['title'] → 现在写成 defineProps<{ title: string }>()。
defineEmits — 向父组件发事件
vue
<script setup>
const emit = defineEmits<{
(e: 'update', id: number): void
(e: 'delete', name: string): void
}>()
function handleClick() {
emit('update', 1) // 触发 update 事件,带参数 1
}
</script>
<template>
<button @click="handleClick">点我更新</button>
</template>
对比选项式 API:在 methods 里用 this.$emit('event') → 现在用 defineEmits 声明并得到 emit 函数。
useSlots / useAttrs
当你不通过 props 传数据,而是用插槽或额外属性时:
vue
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
console.log(slots.default?.()) // 默认插槽的内容
console.log(attrs.class) // 父组件传进来的 class
</script>
这两个用得比较少,初期了解即可。
基础篇所有知识在这里的对照
| 选项式 API | <script setup> | | data() { return { x: 1 } } | const x = ref(1) | | props: ['title'] | defineProps<{ title: string }>() | | methods: { fn() {} } | function fn() {} | | computed: { val() {} } | const val = computed(() => ...) | | watch: { x() {} } | watch(x, (newVal) => ...) | | this.$emit('e') | const emit = defineEmits(); emit('e') | | components: { Comp } | 不用写,import 即可 |
新手常见问题
Q:<script setup> 比选项式 API 快吗? A:性能几乎一样。<script setup> 的好处是开发体验(更少代码、更好 TS 支持、更好逻辑复用)。 Q:能在同一个 .vue 文件里同时用 <script> 和 <script setup> 吗? A:可以,但很少需要这样做。一个文件里只有一个 <script setup>。 下一步: 📝 Note:基础篇回顾 如果你对 Vue 核心概念(条件渲染、事件处理、组件通信等)还不太熟,建议先回到 基础篇 看完,再来深入这里。