Vinculações de Entrada de Formulário
Quando estamos lidando com formulários no frontend, com frequência precisamos sincronizar o estado do elementos de entrada do formulário com estado correspondente em JavaScript. Pode ser desconfortável prender manualmente as vinculações de valor e mudar os ouvintes de evento:
template
<input
:value="text"
@input="event => text = event.target.value">
A diretiva v-model
ajuda-nos a simplificar o que está acima para:
template
<input v-model="text">
Além disto, a v-model
pode ser utilizada nas entradas de tipos diferentes, <textarea>
, e o elemento <select>
. Ela expande automaticamente para propriedade de DOM diferente e pares de eventos baseados no elemento sobre o qual é utilizado:
<input>
com tipos de texto e elementos<textarea>
utilizam a propriedadevalue
e o eventoinput
;<input type="checkbox">
e<input type="radio">
utilizam a propriedadechecked
e o eventochange
;<select>
utilizavalue
como uma propriedade echange
como um evento.
NOTA
A v-model
ignorará o valor inicial dos atributos value
, checked
, ou selected
encontrados em quaisquer elementos de formulário. Ela sempre tratará o atual estado de JavaScript vinculado como a fonte de verdade. Tu podes declarar o valor inicial no lado da JavaScript, utilizando as APIs de reatividade.
Uso Básico
Texto (<input type="text" />
)
template
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
Message is:
NOTA
Para as linguagens que exigem um IME (Chinês, Japonês, Coreano etc.), notarás que a v-model
não é atualizada durante a composição da IME. Se também quiseres responder a estas atualizações, utilize o teu próprio ouvinte de evento input
e vinculação de value
ao invés de utilizar v-model
.
Texto de Várias Linhas (<textarea></textarea>
)
template
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
Multiline message is:
Nota que a interpolação dentro de <textarea>
não funcionará. Utilize v-model
.
template
<!-- bad -->
<textarea>{{ text }}</textarea>
<!-- good -->
<textarea v-model="text"></textarea>
Caixa de Confirmação (<input type="checkbox" />
)
Caixa de confirmação única, valor booleano:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
Nós também podemos vincular várias caixas de confirmação ao mesmo valor de arranjo ou conjunto:
js
const checkedNames = ref([])
template
<div>Checked names: {{ 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>
Checked names: []
Neste caso, o arranjo checkedNames
sempre conterá os valores das caixas confirmadas atualmente.
Rádio (<input type="radio" />
)
template
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
Picked:
Seleção (<select></select>
)
Seleção única:
template
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected:
NOTA
Se o valor inicial da tua expressão de v-model
não corresponder a quaisquer uma das opções, o elemento <select>
interpretará em um estado "não selecionado (unselected)". Na iOS impedirá o utilizador de ser capaz de selecionar o primeiro item uma vez que a iOS não disparará o evento de mudança neste caso. É portanto recomendado fornecer uma opção desativada com um valor vazio, conforme demonstrado no exemplo acima.
Seleção de várias escolhas (vinculadas ao arranjo (array
)):
template
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected: []
As opções do elemento de seleção podem ser dinamicamente interpretadas com a v-for
:
js
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
template
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
Vinculações de Valor
Para rádio, caixa de confirmação e opções de seleção, os valores de vinculação de v-model
são normalmente sequências de caracteres estáticas (ou booleanos para caixa de confirmação):
template
<!-- `picked` é uma sequência de carácter "a" quando for confirmada -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` é ou verdadeiro ou é falso -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` é uma sequência de caracteres "abc" quando a primeira opção for selecionada -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
Mas algumas vezes podes querer vincular o valor a uma propriedade dinâmica na atual instância ativa. Nós podemos utilizar v-bind
para realizar isto. Além disto, utilizando a v-bind
permite-nos vincular o valor de entrada para valores que não sequências de caracteres.
Caixa de Confirmação (<input type="checkbox" />
)
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
A true-value
e false-value
são atributos específicos de Vue que só funcionam com a v-model
. Aqui o valor da propriedade toggle
será definido para 'yes'
quando a caixa for confirmada, e definida para 'no'
quando a confirmação for desfeita. Tu também podes vinculá-los à valores dinâmicos utilizando a v-bind
:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
DICA
Os atributos true-value
e false-value
não afetam o atributo value
da entrada (elemento input
), porque os navegadores não incluem caixas não confirmadas na submissão de formulário. Para garantir que um dos valores é submetido em um formulário (por exemplo "yes" ou "no"), utilize entradas de rádio.
Rádio (<input type="radio" />
)
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
O pick
será definido para o valor de first
quando a primeira entrada de rádio for confirmada, e definida para o valor de second
quando o segundo for confirmado.
Opções de Seleção (<option></option>
)
template
<select v-model="selected">
<!-- literal de objeto em linha -->
<option :value="{ number: 123 }">123</option>
</select>
A v-model
também suporta vinculações de valor de valores que não são sequência de caracteres! No exemplo acima, quando a opção é selecionada, selected
será definida para o valor literal de objeto de { number: 123 }
.
Modificadores
.lazy
Por padrão, a v-model
sincroniza a entrada com o dado depois de cada evento de input
(com a exceção da composição de IME como especificada acima). Tu podes adicionar o modificador lazy
no lugar de sincronizar depois dos eventos change
:
template
<!-- sincronizado depois de "change" no lugar de "input" -->
<input v-model.lazy="msg" />
.number
Se quiseres que a entrada do utilizador seja automaticamente tratada como um número, podes adicionar o modificador number
as tuas entradas geridas pela v-model
:
template
<input v-model.number="age" />
Se o valor não puder ser analisado com parseFloat()
, então o valor original é utilizado no lugar.
O modificador number
é aplicado automaticamente se a entrada tiver o type="number"
.
.trim
Se quiseres que espaços em branco da entrada do utilizador sejam cortados automaticamente, podes adicionar o modificador trim
as tuas entradas geridas pela v-model
:
template
<input v-model.trim="msg" />
v-model
com Componentes
Se ainda não estiveres familiarizados com os componentes da Vue, podes ignorar isto por agora.
Os tipos de entrada embutidos da HTML não irão sempre atender as tuas necessidades. Felizmente, os componentes da Vue permitem-te construir entradas reutilizáveis com comportamentos completamente personalizados. Estas entradas funcionam até com a v-model
! Para aprender mais, leia a respeito Uso com a v-model
no guia de Componentes.