Enlaces de Entrada de Formulario
Al trabajar con formularios en el frontend, a menudo necesitamos sincronizar el estado de los elementos de entrada del formulario con el estado correspondiente en JavaScript. Puede ser engorroso configurar manualmente los enlaces de valor y los oyentes de eventos de cambio:
template
<input
:value="text"
@input="event => text = event.target.value">La directiva v-model nos ayuda a simplificar lo anterior a:
template
<input v-model="text">Además, v-model se puede usar en inputs de diferentes tipos, elementos <textarea> y <select>. Se expande automáticamente a diferentes pares de propiedades DOM y eventos según el elemento en el que se utilice:
- Los
<input>con tipos de texto y los elementos<textarea>usan la propiedadvaluey el eventoinput; - Los
<input type="checkbox">y los<input type="radio">usan la propiedadcheckedy el eventochange; - Los
<select>usanvaluecomo una prop ychangecomo un evento.
Nota
v-model ignorará los atributos value, checked o selected iniciales encontrados en cualquier elemento de formulario. Siempre tratará el estado JavaScript enlazado actual como la fuente de verdad. Debes declarar el valor inicial en el lado de JavaScript, usando las APIs de reactividad.
Uso Básico
Texto
template
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edítame" />El mensaje es:
Nota
Para lenguajes que requieren un IME (chino, japonés, coreano, etc.), notarás que v-model no se actualiza durante la composición del IME. Si también deseas responder a estas actualizaciones, usa tu propio oyente de eventos input y un enlace value en lugar de usar v-model.
Texto Multilínea
template
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="añade múltiples líneas"></textarea>El mensaje multilínea es:
Ten en cuenta que la interpolación dentro de <textarea> no funcionará. Usa v-model en su lugar.
template
<!-- mal -->
<textarea>{{ text }}</textarea>
<!-- bien -->
<textarea v-model="text"></textarea>Casilla de Verificación
Casilla de verificación única, valor booleano:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>También podemos enlazar múltiples casillas de verificación al mismo array o valor de Set:
js
const checkedNames = ref([])template
<div>Nombres seleccionados: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>Nombres seleccionados: []
En este caso, el array checkedNames siempre contendrá los valores de las casillas de verificación actualmente marcadas.
Botón de Radio
template
<div>Seleccionado: {{ picked }}</div>
<input type="radio" id="one" value="Uno" v-model="picked" />
<label for="one">Uno</label>
<input type="radio" id="two" value="Dos" v-model="picked" />
<label for="two">Dos</label>Seleccionado:
Seleccionar
Selección única:
template
<div>Seleccionado: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Por favor selecciona uno</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>Seleccionado:
Nota
Si el valor inicial de tu expresión v-model no coincide con ninguna de las opciones, el elemento <select> se renderizará en un estado "no seleccionado". En iOS, esto provocará que el usuario no pueda seleccionar el primer elemento porque iOS no dispara un evento change en este caso. Por lo tanto, se recomienda proporcionar una opción deshabilitada con un valor vacío, como se demostró en el ejemplo anterior.
Selección múltiple (enlazada a array):
template
<div>Seleccionado: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>Seleccionado: []
Las opciones de selección se pueden renderizar dinámicamente con v-for:
js
const selected = ref('A')
const options = ref([
{ text: 'Uno', value: 'A' },
{ text: 'Dos', value: 'B' },
{ text: 'Tres', value: 'C' }
])template
<div>Seleccionado: {{ selected }}</div>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>Seleccionado: A
Enlaces de Valor
Para las opciones de radio, casilla de verificación y selección, los valores de enlace de v-model suelen ser cadenas estáticas (o booleanos para la casilla de verificación):
template
<!-- `picked` es una cadena "a" cuando está marcado -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` es `true` o `false` -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` es una cadena "abc" cuando la primera opción está seleccionada -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>Pero a veces podemos querer enlazar el valor a una propiedad dinámica en la instancia activa actual. Podemos usar v-bind para lograr eso. Además, usar v-bind nos permite enlazar el valor de input a valores que no son cadenas.
Casilla de Verificación
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />true-value y false-value son atributos específicos de Vue que solo funcionan con v-model. Aquí, el valor de la propiedad toggle se establecerá en 'yes' cuando la casilla esté marcada, y en 'no' cuando esté desmarcada. También puedes enlazarlos a valores dinámicos usando v-bind:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />Consejo
Los atributos true-value y false-value no afectan el atributo value del input, porque los navegadores no incluyen las casillas desmarcadas en los envíos de formularios. Para garantizar que uno de dos valores se envíe en un formulario (por ejemplo, "sí" o "no"), usa inputs de radio en su lugar.
Botón de Radio
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />pick se establecerá al valor de first cuando el primer input de radio esté marcado, y se establecerá al valor de second cuando el segundo esté marcado.
Opciones de Selección
template
<select v-model="selected">
<!-- literal de objeto en línea -->
<option :value="{ number: 123 }">123</option>
</select>v-model también admite enlaces de valor de tipos que no son cadenas. En el ejemplo anterior, cuando se selecciona la opción, selected se establecerá al valor literal del objeto { number: 123 }.
Modificadores
.lazy
Por defecto, v-model sincroniza la entrada con los datos después de cada evento input (con la excepción de la composición IME como se mencionó anteriormente). Puedes añadir el modificador lazy para sincronizar después de los eventos change en su lugar:
template
<!-- sincronizado después de "change" en lugar de "input" -->
<input v-model.lazy="msg" />.number
Si deseas que la entrada del usuario se convierta automáticamente a un número, puedes añadir el modificador number a tus inputs gestionados por v-model:
template
<input v-model.number="age" />Si el valor no puede ser parseado con parseFloat(), se utiliza el valor original (string) en su lugar. En particular, si el input está vacío (por ejemplo, después de que el usuario borre el campo de input), se devuelve una cadena vacía. Este comportamiento difiere de la propiedad DOM valueAsNumber.
El modificador number se aplica automáticamente si el input tiene type="number".
.trim
Si deseas que los espacios en blanco de la entrada del usuario se recorten automáticamente, puedes añadir el modificador trim a tus inputs gestionados por v-model:
template
<input v-model.trim="msg" />v-model con Componentes
Si aún no estás familiarizado con los componentes de Vue, puedes omitir esto por ahora.
Los tipos de input integrados de HTML no siempre satisfarán tus necesidades. Afortunadamente, los componentes de Vue te permiten construir inputs reutilizables con un comportamiento completamente personalizado. ¡Estos inputs incluso funcionan con v-model! Para saber más, lee sobre Uso con v-model en la guía de Componentes.








