Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює defineModel і чим він спрощує v-model на власних компонентах?

v-model на компоненті - це скорочення для пари «prop + подія оновлення»:

<PriceInput v-model="price" />
<!-- те саме, що -->
<PriceInput :modelValue="price" @update:modelValue="(v) => price = v" />

До Vue 3.4 дочірній компонент мусив оголосити prop, подію і зв'язати їх вручну. defineModel (3.4+) робить це одним рядком:

<!-- PriceInput.vue -->
<script setup lang="ts">
const model = defineModel<number>({ required: true })
</script>

<template>
  <input type="number" v-model="model" />
</template>

model - ref: читання повертає значення від батька, присвоєння model.value = 10 випромінює update:modelValue. Компілятор створює і prop modelValue, і подію автоматично.

Кілька моделей і назви:

<!-- батько -->
<DateRange v-model:from="startDate" v-model:to="endDate" />

<!-- DateRange.vue -->
<script setup lang="ts">
const from = defineModel<string>('from')
const to = defineModel<string>('to')
</script>

Модифікатори (v-model.trim) доступні через деструктуризацію:

const [model, modifiers] = defineModel<string>({
  set(value) {
    return modifiers.trim ? value.trim() : value
  },
})

Значення за замовчуванням і розсинхронізація. Якщо модель має default, а батько не передав їй значення (його змінна undefined), дочірній компонент працюватиме зі своїм значенням за замовчуванням: у батька undefined, у дитини, наприклад, 1. Документація прямо попереджає про цю розсинхронізацію - надійніше, щоб початкове значення задавав батько.

Пастки:

  • model.value.push(x) для масиву змінює об'єкт батька напряму, без події - краще присвоювати новий масив (model.value = [...model.value, x]);
  • v-model на <input> усередині з тим самим model - нормальний і найкоротший шлях обгорнути нативне поле.

Докладніше в документації: v-model на компонентах

Схожі питання