# Interligações em Formulários
# Uso Básico
Você pode usar a diretiva v-model
para criar interligações de dados de mão dupla (two-way data binding) em elementos input, textarea e select de formulários. Ela, automaticamente, escolhe a maneira correta de atualizar o elemento baseado no tipo do input. Embora um pouco mágica, v-model
é, essencialmente, uma forma simplificada (syntax sugar) para atualizar dados nos eventos de entrada do usuário, além de cuidado especial com casos extremos.
Nota
v-model
irá ignorar o estado inicial dos atributos value
, checked
ou selected
encontrado em qualquer elemento de formulário. Ela sempre irá tratar os dados da instância ativa como a fonte de informação (source of truth). Você pode declarar o valor inicial no lado do JavasScript, dentro da opção data
de seu componente.
v-model
utiliza diferentes propriedades internamente e emite diferentes eventos para diferentes elementos input:
- elementos text e textarea usam a propriedade
value
e o eventoinput
; - checkboxes e radiobuttons utilizam a propriedade
checked
e o eventochange
; - campos de seleção utilizam
value
como propriedade echange
como um evento.
Nota
Você pode notar que v-model
não é atualizada durante a composição através de um editor de método de entrada (IME (opens new window)), como em Chinês, Japonês, Coreano, etc. Se você também quiser responder a essas atualizações, use diretamente um evento de input
e value
vinculado ao invés da v-model
.
# Input
<input v-model="message" placeholder="Me edite" />
<p>A mensagem é: {{ message }}</p>
2
Veja o exemplo Lidando com Fomulários: v-model simples por vuejs-br (@vuejs-br) no CodePen.
# 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>
2
3
4
Veja o exemplo Lidando com Formulários: textarea por vuejs-br (@vuejs-br) no CodePen.
Interpolação em textareas (<textarea></textarea>
) não funcionará. Em vez disso, use v-model
.
<!-- ruim -->
<textarea>{{ text }}</textarea>
<!-- bom -->
<textarea v-model="text"></textarea>
2
3
4
5
# Checkbox
Caixa de seleção única, valor do tipo boolean:
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
2
Veja o exemplo Lidando com Formulários: checkbox por vuejs-br (@vuejs-br) no CodePen.
Múltiplos checkboxes, associados ao mesmo array:
<div id="v-model-multiple-checkboxes">
<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 selecionados: {{ checkedNames }}</span>
</div>
2
3
4
5
6
7
8
9
10
Vue.createApp({
data() {
return {
checkedNames: []
}
}
}).mount('#v-model-multiple-checkboxes')
2
3
4
5
6
7
Veja o exemplo Lidando com Formulários: múltiplos checkboxes por vuejs-br (@vuejs-br) no CodePen.
# Radio
<div id="v-model-radiobutton">
<input type="radio" id="one" value="Primeiro" v-model="picked" />
<label for="one">Um</label>
<br />
<input type="radio" id="two" value="Segundo" v-model="picked" />
<label for="two">Dois</label>
<br />
<span>Escolhido: {{ picked }}</span>
</div>
2
3
4
5
6
7
8
9
Vue.createApp({
data() {
return {
picked: ''
}
}
}).mount('#v-model-radiobutton')
2
3
4
5
6
7
Veja o exemplo Lidando com Formulários: radiobutton por vuejs-br (@vuejs-br) no CodePen.
# Select
Seleção de um único item:
<div id="v-model-select" class="demo">
<select v-model="selected">
<option disabled value="">Escolha um</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selecionado: {{ selected }}</span>
</div>
2
3
4
5
6
7
8
9
Vue.createApp({
data() {
return {
selected: ''
}
}
}).mount('#v-model-select')
2
3
4
5
6
7
Veja o exemplo Lidando com Formulários: select por vuejs-br (@vuejs-br) no CodePen.
Nota
Se o valor inicial da expressão v-model
não corresponder a nenhuma das opções, o elemento <select>
será renderizado em um estado "não selecionado". No iOS, isso impedirá o usuário de selecionar o primeiro item, já que, neste caso, não há disparo do evento change
. Portanto, é recomendado fornecer uma opção desabilitada 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>Selecionado: {{ selected }}</span>
2
3
4
5
6
7
Veja o exemplo Lidando com Formulários: seleção de múltiplos itens (vinculando a um array) por vuejs-br (@vuejs-br) no CodePen.
Renderização dinâmica de options com v-for
:
<div id="v-model-select-dynamic" class="demo">
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<span>Selecionado: {{ selected }}</span>
</div>
2
3
4
5
6
7
8
Vue.createApp({
data() {
return {
selected: 'A',
options: [
{ text: 'Um', value: 'A' },
{ text: 'Dois', value: 'B' },
{ text: 'Três', value: 'C' }
]
}
}
}).mount('#v-model-select-dynamic')
2
3
4
5
6
7
8
9
10
11
12
Veja o exemplo Lidando com Formulários: select com opções dinâmicas por vuejs-br (@vuejs-br) no CodePen.
# Interligação de Valores
Para radio, checkbox e select, a interligação de valores do v-model
são sempre strings estáticas (ou valores do tipo boolean, em checkboxes):
<!-- `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 a primeira opção for selecionada -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
2
3
4
5
6
7
8
9
10
Porém, às vezes, podemos querer vincular o valor a uma propriedade dinâmica na atual instância ativa. Nós podemos utilizar v-bind
para alcançar isso. Além disso, utilizando v-bind
nos permite vincular o valor de um input para valores que não são uma string (non-string values).
# Checkbox
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
// quando assinalado:
vm.toggle === 'yes'
// quando não assinalado:
vm.toggle === 'no'
2
3
4
Dica
Os atributos true-value
e false-value
não afetam o atributo value
dos inputs, porque os browsers não incluem caixas de seleção não assinaladas nas submissões de formulários. Para garantir que um dos dois valores seja enviado em um formulário (p. ex. "sim" ou "não"), use inputs do tipo radio.
# Radio
<input type="radio" v-model="pick" v-bind:value="a" />
// quando assinalado:
vm.pick === vm.a
2
# Select
<select v-model="selected">
<!-- Objeto literal atribuído para demonstração -->
<option :value="{ number: 123 }">123</option>
</select>
2
3
4
// quando está assinalado:
typeof vm.selected // => 'object'
vm.selected.number // => 123
2
3
# Modificadores
# .lazy
Por padrão, v-model
sincroniza o elemento input com os dados após cada evento input
(exceto para o caso de composição IME, como descrito anteriormente). Você pode adicionar o modificador lazy
para sincronizar depois do evento change
:
<!-- sincronizado depois do "change" ao invés de "input" -->
<input v-model.lazy="msg" />
2
# .number
Se você deseja que a entrada do usuário seja automaticamente tipificada como um Number, pode adicionar o modificador number
ao v-model
do elemento:
<input v-model.number="age" type="text" />
Isso geralmente é útil quando o tipo dp input é text
. Se o tipo do input for number
, o Vue pode converter automaticamente o valor bruto da string para número, e você não precisa adicionar o modificador .number
ao v-model
. Se o valor não puder ser convertido com parseFloat()
, então o valor original é retornado.
# .trim
Se você quiser que os espaços em branco excedentes de um input sejam automaticamente removidos, é possível adicionar o modificador trim
ao v-model
do elemento:
<input v-model.trim="msg" />
# v-model
com Componentes
Se você ainda não está familiarizado com os componentes Vue, pode pular esta parte, por enquanto.
Os tipos de input nativos do HTML nem sempre atendem as suas necessidades. Felizmente, os componentes Vue te permitem construir inputs reutilizáveis com comportamento completamente customizável. Estes componentes também funcionam com v-model
! Para saber mais, leia sobre inputs customizados no guia de Componentes.