Powiązania danych wejściowych formularza
Kiedy mamy do czynienia z formularzami na frontendzie, często musimy synchronizować stan elementów wejściowych formularza z odpowiadającym im stanem w JavaScript. Ręczne tworzenie wiązań wartości i nasłuchiwanie zdarzeń zmiany może być kłopotliwe:
template
<input
:value="text"
@input="event => text = event.target.value">
The v-model
directive helps us simplify the above to:
template
<input v-model="text">
Dodatkowo, v-model
może być używany na elementach wejściowych różnych typów, <textarea>
i <select>
. Automatycznie rozszerza się na różne pary właściwości DOM i zdarzeń, w zależności od elementu, na którym jest użyty:
- Elementy
<input>
z typami tekstowymi i<textarea>
używają właściwościvalue
i zdarzenia -<input type="checkbox">
i<input type="radio">
używają właściwościchecked
i zdarzeniachange
; <select>
używavalue
jako prop ichange
jako event.
Note
v-model
będzie ignorował początkowe value
, checked
or selected
atrybutów znalezionych na dowolnych elementach formularza. Będzie on zawsze traktował bieżący związany stan JavaScript jako źródło prawdy. Wartość początkową należy zadeklarować po stronie JavaScript, używając reaktywność API.
Podstawowe uycie
Tekst
template
<p>Wiadomością jest: {{ message }}</p>
<input v-model="message" placeholder="edytuj mnie" />
Wiadomością jest:
Note
Dla języków, które wymagają IME (chiński, japoński, koreański itd.), zauważysz, że v-model
nie jest aktualizowany podczas tworzenia IME. Jeśli chcesz odpowiadać również na te aktualizacje, użyj listenera zdarzeń input
i wiązania value
zamiast używania v-model
.
Tekst wielowierszowy
template
<span>Wielowierszowa wiadomość to:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="dodaj wiele lini tekstu"></textarea>
Wielowierszowa wiadomość to:
Zauważ, że interpolacja wewnątrz <textarea>
nie będzie działać. Zamiast tego należy użyć v-model
.
template
<!-- źle -->
<textarea>{{ text }}</textarea>
<!-- dobrze -->
<textarea v-model="text"></textarea>
Pole wyboru
Pojedyncze pole wyboru, wartość typu boolean:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
Można także powiązać wiele pól wyboru z tą samą tablicą lub wartością Set:
js
const checkedNames = ref([])
template
<div>Zaznacz imiona: {{ 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>
Zaznacz imiona: []
W tym przypadku tablica checkedNames
będzie zawsze zawierała wartości z aktualnie zaznaczonych pól.
Radio
template
<div>Wybrane: {{ 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>
Wybrane:
Select
Pojedynczy select:
template
<div>Wybrane: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Wybrane:
Note
Jeśli początkowa wartość wyrażenia v-model
nie pasuje do żadnej z opcji, element <select>
będzie renderowany w stanie "unselected". Na iOS spowoduje to, że użytkownik nie będzie mógł wybrać pierwszego elementu, ponieważ iOS nie wywołuje zdarzenia zmiany w tym przypadku. Dlatego zalecane jest zapewnienie opcji wyłączonej z pustą wartością, jak pokazano w powyższym przykładzie.
Wybór wielokrotny (związany z tablicą):
template
<div>Wybrane: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Wybrane: []
Opcje wyboru mogą być dynamicznie renderowane za pomocą 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>Wybrane: {{ selected }}</div>
Value Bindings
For radio, checkbox and select options, the v-model
binding values are usually static strings (or booleans for checkbox):
template
<!-- `picked` is a string "a" when checked -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` is either true or false -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` is a string "abc" when the first option is selected -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
Czasami jednak możemy chcieć powiązać wartość z dynamiczną właściwością na bieżącej aktywnej instancji. Możemy użyć v-bind
, aby to osiągnąć. Dodatkowo, użycie v-bind
pozwala nam powiązać wartość wejściową z wartościami, które nie są ciągami znaków.
Checkbox
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value
i false-value
są atrybutami specyficznymi dla Vue, które działają tylko z v-model
. Tutaj wartość właściwości toggle
będzie ustawiona na 'yes'
gdy pole jest zaznaczone, i ustawiona na 'no'
gdy jest odznaczone. Możesz także powiązać je z dynamicznymi wartościami używając v-bind
:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
Tip
Atrybuty true-value
i false-value
nie wpływają na atrybut value
wejścia, ponieważ przeglądarki nie uwzględniają niezaznaczonych pól we wnioskach formularzy. Aby zagwarantować, że w formularzu zostanie podana jedna z dwóch wartości (np. "tak" lub "nie"), należy użyć wejść radiowych.
Radio
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
pick
zostanie ustawiony na wartość first
, gdy zostanie zaznaczone pierwsze wejście radiowe, oraz na wartość second
, gdy zostanie zaznaczone drugie.
Select Options
template
<select v-model="selected">
<!-- inline object literal -->
<option :value="{ number: 123 }">123</option>
</select>
v-model
obsługuje także wiązania wartości, które nie są ciągiem znaków! W powyższym przykładzie, gdy opcja zostanie wybrana, selected
zostanie ustawiony na literalną wartość obiektu { liczba: 123 }
.
Modyfikatory
.lazy
Domyślnie, v-model
synchronizuje dane wejściowe z danymi po każdym zdarzeniu input
(z wyjątkiem kompozycji IME, jak podano wyżej). Możesz dodać modyfikator lazy
aby zamiast tego synchronizować po zdarzeniach change
:
template
<!-- zsynchronizowane po "change" zamiast "input" -->
<input v-model.lazy="msg" />
.number
Jeśli chcesz, aby dane wejściowe użytkownika były automatycznie zamieniane na liczbę, możesz dodać modyfikator number
do danych wejściowych zarządzanych przez v-model
:
template
<input v-model.number="age" />
Jeśli wartość nie może być przetworzona przy pomocy parseFloat()
, to zamiast niej używana jest wartość oryginalna.
Modyfikator number
jest stosowany automatycznie, jeśli dane wejściowe mają type="number"
.
.trim
Jeśli chcesz, by białe spacje z danych wejściowych użytkownika były automatycznie obcinane, możesz dodać modyfikator trim
do danych wejściowych zarządzanych przez v-model
:
template
<input v-model.trim="msg" />
v-model
z Komponentami
Jeśli nie jesteś jeszcze zaznajomiony z komponentami Vue, możesz na razie pominąć tę część.
Wbudowane w HTML typy danych wejściowych nie zawsze spełniają Twoje potrzeby. Na szczęście, komponenty Vue pozwalają na budowanie wejść wielokrotnego użytku z całkowicie spersonalizowanym zachowaniem. Te dane wejściowe działają nawet z v-model
! Aby dowiedzieć się więcej, przeczytaj o Użycie v-model
w przewodniku po komponentach.