Skip to main content
Практика завдань

defineProps, defineEmits та defineExpose у Vue.js

Макроси Script Setup

<script setup> у Vue 3 надає макроси компілятора, які спрощують оголошення компонентів. Ці макроси автоматично доступні — імпорти не потрібні.


defineProps

Оголосіть пропси, які компонент приймає:

vue
<script setup lang="ts"> // Оголошення на основі типів (рекомендується) const props = defineProps<{ title: string count?: number items: string[] user: { name: string; age: number } }>() // Доступ до пропсів console.log(props.title) </script>

З значеннями за замовчуванням

vue
<script setup lang="ts"> const props = withDefaults( defineProps<{ title: string count?: number theme?: 'light' | 'dark' items?: string[] }>(), { count: 0, theme: 'light', items: () => [], // Використовуйте фабричну функцію для об'єктів/масивів } ) </script>

Оголошення під час виконання

vue
<script setup> const props = defineProps({ title: { type: String, required: true }, count: { type: Number, default: 0 }, items: { type: Array, default: () => [] }, }) </script>

defineEmits

Оголосіть події, які компонент може випускати:

vue
<script setup lang="ts"> const emit = defineEmits<{ change: [value: string] submit: [data: { name: string }] close: [] }>() function handleChange(e: Event) { emit('change', (e.target as HTMLInputElement).value) } function handleSubmit() { emit('submit', { name: 'Alice' }) } </script>

defineExpose

Експонуйте методи/властивості компонента батьківському компоненту через рефери шаблону:

vue
<!-- ChildComponent.vue --> <script setup> import { ref } from 'vue' const count = ref(0) function reset() { count.value = 0 } function focus() { // Логіка фокусування } // За замовчуванням нічого не експонується з <script setup> // Явно експонуйте те, до чого можуть отримати доступ батьки: defineExpose({ count, reset, focus }) </script>
vue
<!-- ParentComponent.vue --> <script setup> import { ref } from 'vue' import ChildComponent from './ChildComponent.vue' const childRef = ref<InstanceType<typeof ChildComponent> | null>(null) function resetChild() { childRef.value?.reset() // ✅ Доступно завдяки defineExpose childRef.value?.count // ✅ Доступно } </script> <template> <ChildComponent ref="childRef" /> <button @click="resetChild">Скинути дитину</button> </template>

defineModel (Vue 3.4+)

Спрощує прив'язку v-model:

vue
<!-- CustomInput.vue --> <script setup> const model = defineModel<string>() // Еквівалентно: props.modelValue + emit('update:modelValue') </script> <template> <input v-model="model" /> </template> <!-- Parent.vue --> <CustomInput v-model="name" />

Іменовані моделі

vue
<script setup> const firstName = defineModel<string>('firstName') const lastName = defineModel<string>('lastName') </script> <!-- <UserForm v-model:firstName="first" v-model:lastName="last" /> -->

Резюме

МакросПризначенняПотрібен імпорт?
definePropsОголосити пропси компонентаНі
defineEmitsОголосити події компонентаНі
defineExposeЕкспонувати API через реф шаблонуНі
defineModelДвостороннє зв'язування (v-model)Ні
withDefaultsЗначення за замовчуванням для пропсівНі

Важливо:

Ці макроси є трансформаціями компілятора — вони не існують під час виконання і не потребують імпортів. Використовуйте defineProps з генераками TypeScript для типобезпечних пропсів, defineEmits для типізованих подій, defineExpose для контролю доступу батьків, а також defineModel (Vue 3.4+) для спрощеного v-model.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань