script setup и макросы компилятора

↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

<script setup> — стандарт; вопросы про макросы (defineProps, defineEmits, defineModel) и почему их не нужно импортировать.

Объяснение

<script setup> — синтаксический сахар для Composition API в SFC: код выполняется при создании компонента, все верхнеуровневые привязки (переменные, функции, импорты) доступны в шаблоне без return.

<script setup lang="ts">
import { ref } from "vue";
import OrderRow from "./OrderRow.vue";                      // компонент доступен в шаблоне без регистрации
 
interface Props { orders: Order[]; page?: number }
const props = withDefaults(defineProps<Props>(), { page: 1 });
const emit = defineEmits<{ select: [id: number]; "update:page": [page: number] }>();
const model = defineModel<string>("query", { default: "" });
defineOptions({ name: "OrdersTable", inheritAttrs: false });
defineExpose({ reset });                                    // публичный API компонента
 
const selected = ref<number | null>(null);
function reset() { selected.value = null; }
await Promise.resolve();                                     // top-level await → нужен <Suspense>
</script>
МакросНазначение
definePropsобъявление props (типы выводятся из TS-интерфейса)
defineEmitsсобытия
defineModelv-model (props + emit)
defineExposeчто доступно через template ref
defineOptionsимя, inheritAttrs и др.
defineSlotsтипизация слотов
withDefaultsзначения по умолчанию для типизированных props

Макросы — compile-time: компилятор преобразует их в обычные опции, импортировать их не нужно; аргументы не могут ссылаться на локальные переменные setup (кроме констант/импортов). Реактивная деструктуризация props (Vue 3.5) сохраняет реактивность: const { page = 1 } = defineProps<Props>().

Отличие от setup(): компактнее, лучше производительность (шаблон компилируется в замыкание внутри setup), лучшая поддержка TS.

Нюансы и подводные камни

  • По умолчанию компонент «закрыт»: снаружи (через ref родителя) доступно только то, что в defineExpose.
  • Нельзя использовать export default вместе с <script setup> (для этого второй обычный <script>).
  • Дефолты объектов/массивов в withDefaults задаются фабриками.
  • Для рекурсивных компонентов — имя файла или defineOptions({ name }).
  • Директивы: локальные с префиксом v (vFocus).

Практика

  1. Объявите типизированные props, emits и defineModel.
  2. Экспортируйте метод компонента через defineExpose и вызовите из родителя.
  3. Используйте локальную директиву vFocus.

Вопросы с ответами

Связанные темы