Il v-model sui componenti 
v-model può essere utilizzato su un componente per implementare un legame bidirezionale.
Prima di tutto, rivediamo come viene utilizzato v-model su un elemento nativo:
template
<input v-model="searchText" />Nel backend, il compilatore del template espande v-model in un modo più verboso. Quindi, il codice sopra fa la stessa cosa del seguente:
template
<input
  :value="searchText"
  @input="searchText = $event.target.value"
/>Quando usato su un componente, v-model invece si espande in questo modo:
template
<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>Affinché ciò funzioni effettivamente, il componente <CustomInput> deve fare due cose:
- Collegare l'attributo valuedi un elemento<input>alla propmodelValue
- Quando scatta un evento nativo inputemettere un evento personalizzatoupdate:modelValuecon il nuovo valore
Una dimostrazione pratica:
vue
<!-- CustomInput.vue -->
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>Ora il v-model dovrebbe funzionare perfettamente con questo componente:
template
<CustomInput v-model="searchText" />Un altro modo per implementare v-model all'interno di questo componente è utilizzare una proprietà computed scrivibile con sia un getter che un setter. Il metodo get dovrebbe restituire la proprietà modelValue e il metodo set dovrebbe emettere l'evento corrispondente:
vue
<!-- CustomInput.vue -->
<script setup>
import { computed } from 'vue'
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const value = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  }
})
</script>
<template>
  <input v-model="value" />
</template>Argomenti v-model 
Per impostazione predefinita, v-model su un componente utilizza modelValue come prop e update:modelValue come evento. Possiamo modificare questi nomi passando un argomento a v-model:
template
<MyComponent v-model:title="bookTitle" />In questo caso, il componente figlio dovrebbe aspettarsi una prop title ed emettere un evento update:title per aggiornare il valore nel componente genitore:
vue
<!-- MyComponent.vue -->
<script setup>
defineProps(['title'])
defineEmits(['update:title'])
</script>
<template>
  <input
    type="text"
    :value="title"
    @input="$emit('update:title', $event.target.value)"
  />
</template>Molteplici v-model 
Sfruttando la capacità di specificare una prop e un evento particolari come abbiamo imparato precedentemente con gli argomenti del v-model, ora possiamo creare più collegamenti v-model su una singola istanza del componente.
Ogni v-model si sincronizzerà con una prop diversa, senza bisogno di opzioni aggiuntive nel componente:
template
<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>vue
<script setup>
defineProps({
  firstName: String,
  lastName: String
})
defineEmits(['update:firstName', 'update:lastName'])
</script>
<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>Gestire i modificatori del v-model 
Quando abbiamo imparato a proposito dei vincoli per gli input nei form, abbiamo visto che v-model ha modificatori integrati - .trim, .number e .lazy. In alcuni casi, potresti anche voler supportare modificatori personalizzati per il v-model nel tuo componente input personalizzato.
Creiamo un esempio di modificatore personalizzato chiamato capitalize, che rende maiuscola la prima lettera della stringa fornita dal binding v-model:
template
<MyComponent v-model.capitalize="myText" />I modificatori aggiunti a un componente v-model saranno forniti al componente tramite la prop modelModifiers. Nell'esempio qui sotto, abbiamo creato un componente che contiene una prop modelModifiers che per impostazione predefinita è un oggetto vuoto:
vue
<script setup>
const props = defineProps({
  modelValue: String,
  modelModifiers: { default: () => ({}) }
})
defineEmits(['update:modelValue'])
console.log(props.modelModifiers) // { capitalize: true }
</script>
<template>
  <input
    type="text"
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>Nota che la prop modelModifiers del componente contiene capitalize e il suo valore è true - perché è stato impostato sul binding v-model v-model.capitalize="myText".
Ora che abbiamo la nostra prop impostata, possiamo controllare le chiavi dell'oggetto modelModifiers e scrivere un gestore per cambiare il valore emesso. Nel codice qui sotto, rendiamo maiuscola la stringa ogni volta che l'elemento <input /> scatena un evento input.
vue
<script setup>
const props = defineProps({
  modelValue: String,
  modelModifiers: { default: () => ({}) }
})
const emit = defineEmits(['update:modelValue'])
function emitValue(e) {
  let value = e.target.value
  if (props.modelModifiers.capitalize) {
    value = value.charAt(0).toUpperCase() + value.slice(1)
  }
  emit('update:modelValue', value)
}
</script>
<template>
  <input type="text" :value="modelValue" @input="emitValue" />
</template>Modificatori per il v-model con argomenti 
Per i binding v-model con sia un argomento che dei modificatori, il nome della prop generata sarà arg + "Modifiers". Ad esempio:
template
<MyComponent v-model:title.capitalize="myText">Le dichiarazioni corrispondenti dovrebbero essere:
js
const props = defineProps(['title', 'titleModifiers'])
defineEmits(['update:title'])
console.log(props.titleModifiers) // { capitalize: true }Ecco un altro esempio di utilizzo dei modificatori con più v-model con argomenti diversi:
template
<UserName
  v-model:first-name.capitalize="first"
  v-model:last-name.uppercase="last"
/>vue
<script setup>
const props = defineProps({
  firstName: String,
  lastName: String,
  firstNameModifiers: { default: () => ({}) },
  lastNameModifiers: { default: () => ({}) }
})
defineEmits(['update:firstName', 'update:lastName'])
console.log(props.firstNameModifiers) // { capitalize: true }
console.log(props.lastNameModifiers) // { uppercase: true}
</script>