Skip to content

Latest commit

 

History

History
289 lines (218 loc) · 9.48 KB

forms.md

File metadata and controls

289 lines (218 loc) · 9.48 KB

Interligações em Formulários

Aprenda a trabalhar com inputs de formulário com uma aula gratuita da Vue School

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.

::: tip 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.

::: tip 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), 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>

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>

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

<!-- ruim -->
<textarea>{{ text }}</textarea>

<!-- bom -->
<textarea v-model="text"></textarea>

Checkbox

Caixa de seleção única, valor do tipo boolean:

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

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>
Vue.createApp({
  data() {
    return {
      checkedNames: []
    }
  }
}).mount('#v-model-multiple-checkboxes')

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>
Vue.createApp({
  data() {
    return {
      picked: ''
    }
  }
}).mount('#v-model-radiobutton')

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>
Vue.createApp({
  data() {
    return {
      selected: ''
    }
  }
}).mount('#v-model-select')

:::tip 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>

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>
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')

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>

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'

:::tip 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

Select

<select v-model="selected">
  <!-- Objeto literal atribuído para demonstração -->
  <option :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 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" />

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