v-model несумісно
Огляд
Огляд змін на високому рівні:
- НЕСУМІСНО: При використанні на користувальницьких компонентах типові назви реквізитів і подій
v-modelзмінюються:- реквізит:
value->modelValue; - поді':
input->update:modelValue;
- реквізит:
- НЕСУМІСНО: Модифікатор
.syncі параметрmodelкомпонентаv-bindвидалено та замінено аргументомv-model; - НОВЕ: Тепер можливі кілька прив'язок
v-modelдо одного компонента; - НОВЕ: Додано можливість створювати власні модифікатори
v-model.
Щоб дізнатися більше, читайте далі!
Введення
Коли було випущено Vue 2.0, директива v-model вимагала від розробників завжди використовувати властивість value. І якби розробникам потрібні були різні властивості для різних цілей, їм довелося б вдатися до використання v-bind.sync. Крім того, цей жорстко закодований зв'язок між v-model і value призводив до проблем із тим, як оброблялися нативні та користувацькі елементи.
У версії 2.2 ми представили опцію компонента model, яка дозволяє компоненту налаштовувати властивість і подію для використання в v-model. Однак це все ще дозволяло використовувати лише одну v-модель для компонента.
У Vue 3 API двостороннє зв'язування даних стандартизовано, щоб зменшити плутанину та надати розробникам більше гнучкості за допомогою директиви v-model.
Синтакс 2.x
У 2.x використання v-model для компонента було еквівалентом передачі реквізиту value і випромінювання події input:
<ChildComponent v-model="pageTitle" />
<!-- було б скороченням для: -->
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />Якщо ми хочемо змінити назви реквізитів або подій на щось інше, нам потрібно буде додати опцію model до компонента ChildComponent:
<!-- ParentComponent.vue -->
<ChildComponent v-model="pageTitle" />// ChildComponent.vue
export default {
model: {
prop: 'title',
event: 'change'
},
props: {
// це дозволяє використовувати реквізит `value` для іншої мети
value: String,
// використовуйте `title` як реквізит, який займає місце `value`
title: {
type: String,
default: 'Назва за замовчуванням'
}
}
}Отже, v-model у цьому випадку буде скороченням до
<ChildComponent :title="pageTitle" @change="pageTitle = $event" />Використання v-bind.sync
У деяких випадках нам може знадобитися «двостороннє прив'язування» для реквізиту (іноді на додаток до існуючої v-model для іншого реквізиту). Для цього ми рекомендуємо видавати події за шаблоном update:myPropName. Наприклад, для ChildComponent з попереднього прикладу з атрибутом title ми могли б повідомити намір призначити нове значення за допомогою:
this.$emit('update:title', newValue)Тоді батьківський компонент може прослухати цю подію та оновити властивість локальних даних, якщо захоче. Наприклад:
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />Для зручності ми мали скорочення цього шаблону з модифікатором .sync:
<ChildComponent :title.sync="pageTitle" />Синтаксис 3.x
У версії 3.x v-model для спеціального компонента є еквівалентом передачі реквізиту modelValue і випромінювання події update:modelValue:
<ChildComponent v-model="pageTitle" />
<!-- було б скороченням для: -->
<ChildComponent
:modelValue="pageTitle"
@update:modelValue="pageTitle = $event"
/>Аргументи v-model
Щоб змінити назву моделі, замість опції компонента model, тепер ми можемо передати аргумент до v-model:
<ChildComponent v-model:title="pageTitle" />
<!-- було б скороченням для: -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
Це також слугує заміною модифікатора .sync і дозволяє нам мати кілька v-model у користувацькому компоненті.
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
<!-- було б скороченням для: -->
<ChildComponent
:title="pageTitle"
@update:title="pageTitle = $event"
:content="pageContent"
@update:content="pageContent = $event"
/>Модифікатори v-model
На додаток до жорстко закодованих модифікаторів v-model 2.x, таких як .trim, тепер 3.x підтримує спеціальні модифікатори:
<ChildComponent v-model.capitalize="pageTitle" />Докладніше про спеціальні модифікатори v-model в компонентах.
Стратегія міграції
Ми рекомендуємо:
перевірити кодову базу на використання
.syncі замінити його наv-model:html<ChildComponent :title.sync="pageTitle" /> <!-- замінити на --> <ChildComponent v-model:title="pageTitle" />для всіх
v-modelбез аргументів переконайтеся, що змінено реквізити та назви подій наmodelValueтаupdate:modelValueвідповідноhtml<ChildComponent v-model="pageTitle" />js// ChildComponent.vue export default { props: { modelValue: String // раніше було `value: String` }, emits: ['update:modelValue'], methods: { changePageTitle(title) { this.$emit('update:modelValue', title) // раніше було `this.emit('input', title)` } } }
COMPONENT_V_MODELCOMPILER_V_BIND_SYNC
Наступні кроки
Додаткову інформацію про новий синтаксис v-model див.