# 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 evento input;
  • checkboxes e radiobuttons utilizam a propriedade checked e o evento change;
  • campos de seleção utilizam value como propriedade e change 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 atender a essas atualizações, use diretamente o evento de input ao invés da v-model.

# Input

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

Veja o Pen Lidando com Fomulários: v-model simples Vue.js Brasil (@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>
1
2
3
4

Veja o Pen Lidando com Formulários: textarea Vue.js Brasil (@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>
1
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>
1
2

Veja o Pen Lidando com Formulários: checkbox Vue.js Brasil (@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>
1
2
3
4
5
6
7
8
9
10
Vue.createApp({
  data() {
    return {
      checkedNames: []
    }
  }
}).mount('#v-model-multiple-checkboxes')
1
2
3
4
5
6
7

Veja o Pen Lidando com Formulários: múltiplos checkboxes Vue.js Brasil (@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>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      picked: ''
    }
  }
}).mount('#v-model-radiobutton')
1
2
3
4
5
6
7

Veja o Pen Lidando com Formulários: radiobutton Vue.js Brasil (@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>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      selected: ''
    }
  }
}).mount('#v-model-select')
1
2
3
4
5
6
7

Veja o Pen Lidando com Formulários: select Vue.js Brasil (@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>
1
2
3
4
5
6
7

Veja o Pen Lidando com Formulários: seleção de múltiplos itens (vinculando a um array) por Vue.js Brasil (@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>
1
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')
1
2
3
4
5
6
7
8
9
10
11
12

Veja o Pen Lidando com Formulários: select com opções dinâmicas por Vue.js Brasil (@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>
1
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" />
1
// quando assinalado:
vm.toggle === 'yes'
// quando não assinalado:
vm.toggle === 'no'
1
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" />
1
// quando assinalado:
vm.pick === vm.a
1
2

# Select

<select v-model="selected">
  <!-- Objeto literal atribuído para demonstração -->
  <option :value="{ number: 123 }">123</option>
</select>
1
2
3
4
//  quando está assinalado:
typeof vm.selected // => 'object'
vm.selected.number // => 123
1
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" />
1
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="number" />
1

Isto geralmente é útil, porque mesmo com type="number", o valor do elemento HTML input sempre retorna uma string. 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" />
1

# 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.

Deployed on Netlify.
Atualizado pela última vez: 9/30/2020, 12:16:28 AM