Interligações em Formulários

Uso Básico

Você pode usar a diretiva v-model para criar interligações de mão dupla (two-way binding) entre os dados e elementos como input e textarea de formulários. A diretiva automaticamente busca a maneira correta de atualizar o elemento com base no tipo de entrada. Embora um pouco mágico, v-model é essencialmente açúcar sintático para atualização de dados através de eventos de entrada do usuário, além de cuidados especiais para alguns casos extremos.

A diretiva v-model irá ignorar o estado inicial de value, checked ou selected encontrado em qualquer elemento de formulário. Sempre se tratará a instância Vue como a fonte dos dados verdadeiros. Ou seja, declare os valores iniciais no lado JavaScript, dentro da opção data de seu componente.

Para linguagens que requerem um IME (Chinês, Japonês, Coreano etc.), você notará que v-model não é atualizado durante a atualização da composição IME. Se você quiser atender a estas atualizações, use o evento input ao invés do v-model.

Input

<input v-model="message" placeholder="Me edite">
<p>A mensagem é: {{ message }}</p>

A mensagem é: {{ message }}

Textarea

<span>Mensagem com múltiplas linhas:</span>
<p style="white-space: pre-line">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="Escreva bastante"></textarea>
Mensagem com múltiplas linhas:

{{ message }}


Interpolação em textareas (<textarea>{{text}}</textarea>) não funciona. Em vez disso, sempre use v-model.

Checkbox

Checkbox simples com valor boleano:

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

Múltiplos checkboxes, associados a um mesmo Array:

<div id="example-3">
<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>
<br>
<span>Nomes assinalados: {{ checkedNames }}</span>
</div>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})

Nomes assinalados: {{ checkedNames }}

Radio

<input type="radio" id="one" value="Um" v-model="picked">
<label for="one">Um</label>
<br>
<input type="radio" id="two" value="Dois" v-model="picked">
<label for="two">Dois</label>
<br>
<span>Escolhido: {{ picked }}</span>


Escolhido: {{ picked }}

Select

Seleção de um único item:

<select v-model="selected">
<option disabled value="">Escolha um item</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selecionado: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: ''
}
})

Selecionado: {{ selected }}

Se o valor inicial da expressão v-model não corresponder a nenhuma das opções, o <select> será renderizado como “não selecionado”. No iOS, isso impedirá o usuário de selecionar o primeiro item, pois não há disparo de eventos de alteração neste caso. Recomenda-se fornecer uma opção desativada com um valor vazio, como demonstrado no exemplo acima.

Seleção de múltiplos itens (vinculando a um Array):

<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selecionados: {{ selected }}</span>

Selecionados: {{ selected }}

É possível renderizar dinamicamente as options com v-for:

<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<br>
<span>Selecionado: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'Um', value: 'A' },
{ text: 'Dois', value: 'B' },
{ text: 'Três', value: 'C' }
]
}
})

Selecionado: {{ selected }}

Vinculando aos Valores

Para radio, checkbox e options de select, os valores de vinculação do v-model são normalmente Strings estáticas (ou boleano no caso do checkbox):

<!-- `picked` é uma string "a" quando assinalado -->
<input type="radio" v-model="picked" value="a">
<!-- `toggle` é verdadeiro ou falso -->
<input type="checkbox" v-model="toggle">
<!-- `selected` é uma string "abc" quando assinalado -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>

Mas, às vezes, podemos querer vincular o valor de uma propriedade dinâmica disponível na instância Vue. Podemos usar v-bind para alcançar este objetivo. Além disso, usar v-bind nos permite vincular o valor de inputs para valores não-String.

Checkbox

<input
type="checkbox"
v-model="toggle"
v-bind:true-value="a"
v-bind:false-value="b"
>
// quando está assinalado:
vm.toggle === vm.a
// quando não está assinalado:
vm.toggle === vm.b

Radio

<input type="radio" v-model="pick" v-bind:value="a">
// quando está assinalado:
vm.pick === vm.a

Select

<select v-model="selected">
<!-- Objeto literal atribuído para demonstração -->
<option v-bind:value="{ number: 123 }">123</option>
</select>
// quando está assinalado:
typeof vm.selected // => 'object'
vm.selected.number // => 123

Modificadores

.lazy

Por padrão, v-model sincroniza o elemento com os dados após cada evento do tipo input (com exceção para o caso de composição IME descrito anteriormente). Adicionando o modificador lazy, a sincronização ocorrerá somente após o evento change:

<!-- sincronizado depois do "change" ao invés de "input" -->
<input v-model.lazy="msg" >

.number

Se você quiser que a entrada do usuário seja automaticamente convertida para um número, pode ser feito adicionando o modificador number ao v-model do elemento:

<input v-model.number="age" type="number">

Isso é bastante útil, porque mesmo no caso de type="number", o valor retornado pelo HTML é sempre uma String.

.trim

Se você quiser que a entrada do usuário seja automaticamente isenta de espaços no início e no fim do texto, você pode adicionar o modificador trim ao v-model do elemento:

<input v-model.trim="msg">

v-model com Componentes

Se você não está familiarizado com componentes Vue, apenas pule isto por enquanto.

Os tipo de input nativos do HTML nem sempre atendem todas as necessidades. Por sorte, componentes Vue permitem construir inputs reutilizáveis com comportamento completamente personalizado. Estes componentes também funcionam com v-model! Para saber mais, leia sobre componentes de formulário personalizados no guia de Componentes.