<script setup> es la forma recomendada de escribir componentes Vue usando la Composition API. Elimina el código repetitivo que de otro modo tendrías que escribir manualmente, así que dedicas menos tiempo al código de conexión y más a la lógica real.
Antes y después
Sin <script setup>, un componente de Composition API requiere export default, una función setup(), y una declaración return explícita que liste todo lo que la plantilla necesita:
<!-- Sin <script setup> — mucho código repetitivo -->
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
export default defineComponent({
props: {
initialCount: { type: Number, default: 0 }
},
emits: ['update'],
setup(props, { emit }) {
const count = ref(props.initialCount)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
emit('update', count.value)
}
return { count, doubled, increment }
}
})
</script>Con <script setup>, todo eso desaparece. Cada variable, función e importación del nivel superior queda disponible automáticamente en la plantilla:
<!-- Con <script setup> — mismo resultado, la mitad del código -->
<script setup lang="ts">
import { ref, computed } from 'vue'
const props = defineProps<{ initialCount?: number }>()
const emit = defineEmits<{ update: [value: number] }>()
const count = ref(props.initialCount ?? 0)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
emit('update', count.value)
}
</script>Sin export default. Sin función setup(). Sin declaración return. Todo lo declarado en el nivel superior se expone a la plantilla automáticamente.
Macros del compilador
<script setup> introduce macros del compilador — funciones especiales que el compilador de Vue procesa en tiempo de compilación. No necesitan importarse:
defineProps— declara props con inferencia completa de tipos TypeScriptdefineEmits— declara los eventos que el componente puede emitirdefineModel— declara una prop de enlace bidireccional (v-model)defineExpose— expone explícitamente valores a las refs de plantilla del padre
<script setup lang="ts">
const props = defineProps<{ title: string }>()
const emit = defineEmits<{ close: [] }>()
const model = defineModel<string>()
defineExpose({ reset() { /* ... */ } })
</script>Cuándo todavía necesitas un <script> normal
Ocasionalmente necesitas tanto <script setup> como un bloque <script> normal en el mismo componente — por ejemplo, para establecer inheritAttrs: false o declarar exportaciones con nombre:
<script lang="ts">
export default { inheritAttrs: false }
</script>
<script setup lang="ts">
const attrs = useAttrs()
</script>Esto es poco frecuente. Para la gran mayoría de componentes, <script setup> solo es todo lo que necesitas.
Ver también: ¿Cuáles son todas las macros del compilador en Vue? · ¿Qué es la Composition API y en qué se diferencia de la Options API?
Referencias
- <script setup> - Vue.js docs
- Composition API FAQ - Vue.js docs
- SFC Syntax Specification - Vue.js docs