Skip to content

Прив'язування елементів форми

Коли ми маємо справу з формами на фронтенді, нам часто потрібно синхронізувати стан елементів введення форми з відповідним станом у JavaScript. Вручну підключати зв'язки значень і змінювати слухачів подій може бути громіздким:

template
<input
  :value="text"
  @input="event => text = event.target.value">

Директива v-model допомагає нам спростити вищезазначене:

template
<input v-model="text">

Крім того, v-model можна використовувати для елементів різних типів, таких як <textarea> і <select>. Вона автоматично розширюється до різних пар властивостей і подій DOM на основі елемента, у якому ця директива використовується:

  • <input> з текстовими типами та елементами <textarea> використовують властивість value та подію input;
  • <input type="checkbox"> і <input type="radio"> використовують властивість checked і подію change;
  • <select> використовує value як властивість і change як подію.

Примітка

v-model ігноруватиме початкові атрибути value, checked або selected, знайдені в будь-яких елементах форми. Він завжди розглядатиме поточний зв'язаний стан JavaScript як джерело правди. Вам слід оголосити початкове значення на стороні JavaScript, використовуючи параметр dataAPI реактивності.

Основне використання

Текст

template
<p>Повідомлення: {{ message }}</p>
<input v-model="message" placeholder="Відредагуй мене" />

Повідомлення:

Примітка

Для мов, для яких потрібен IME (китайська, японська, корейська тощо), ви помітите, що v-model не оновлюється під час створення IME. Якщо ви також хочете реагувати на ці оновлення, використовуйте власний input слухач подій і зв'язування value замість використання v-model.

Багаторядковий текст

template
<span>Багаторядкове повідомлення:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="додайте кілька рядків"></textarea>
Багаторядкове повідомлення:

Зауважте, що інтерполяція всередині <textarea> не працюватиме. Замість цього використовуйте v-model.

template
<!-- погано -->
<textarea>{{ text }}</textarea>

<!-- добре -->
<textarea v-model="text"></textarea>

Прапорець

Один прапорець, логічне значення:

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

Ми також можемо прив'язати кілька прапорців до одного масиву або значення Set:

js
const checkedNames = ref([])
js
export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
template
<div>Вибрані імена: {{ checkedNames }}</div>

<input type="checkbox" id="olha" value="Ольга" v-model="checkedNames">
<label for="olha">Ольга</label>

<input type="checkbox" id="dariia" value="Дарія" v-model="checkedNames">
<label for="dariia">Дарія</label>

<input type="checkbox" id="victoria" value="Вікторія" v-model="checkedNames">
<label for="victoria">Вікторія</label>
Вибрані імена: []

У цьому випадку масив checkedNames завжди міститиме значення з поточних прапорців.

Радіокнопка

template
<div>Вибрано: {{ picked }}</div>

<input type="radio" id="one" value="Один" v-model="picked" />
<label for="one">Один</label>

<input type="radio" id="two" value="Два" v-model="picked" />
<label for="two">Два</label>
Вибрано:

Поле вибору

Поле одиночного вибору:

template
<div>Вибрано: {{ selected }}</div>

<select v-model="selected">
  <option disabled value="">Будь ласка, оберіть варіант</option>
  <option>А</option>
  <option>Б</option>
  <option>В</option>
</select>
Вибрано:

Примітка

Якщо початкове значення виразу v-model не відповідає жодному з варіантів, елемент <select> показуватиметься в стані "не вибрано". В iOS це призведе до того, що користувач не зможе вибрати перший елемент, оскільки в цьому випадку iOS не запускає подію зміни. Тому рекомендується вказати вимкнений параметр із порожнім значенням, як показано у прикладі вище.

Поле множинного вибору (прив'язано до масиву):

template
<div>Вибрано: {{ selected }}</div>

<select v-model="selected" multiple>
  <option>А</option>
  <option>Б</option>
  <option>В</option>
</select>
Вибрано: []

Вибрані параметри можна динамічно показувати за допомогою v-for:

js
const selected = ref('А')

const options = ref([
  { text: 'Один', value: 'Б' },
  { text: 'Два', value: 'В' },
  { text: 'Три', value: 'Г' }
])
js
export default {
  data() {
    return {
      selected: 'А',
      options: [
        { text: 'Один', value: 'Б' },
        { text: 'Два', value: 'В' },
        { text: 'Три', value: 'Г' }
      ]
    }
  }
}
template
<select v-model="selected">
  <option v-for="option in options" :key="option.value" :value="option.value">
    {{ option.text }}
  </option>
</select>

<div>Вибрано: {{ selected }}</div>

Прив'язування значень

Для радіокнопок, прапорця та поля вибору прив'язування v-model зазвичай є статичними рядками (або логічними значеннями для прапорця):

template
<!-- `picked` - це рядок "а", якщо позначено прапорцем -->
<input type="radio" v-model="picked" value="а" />

<!-- `toggle` має значення true або false -->
<input type="checkbox" v-model="toggle" />

<!-- `selected` - це рядок "абв", коли вибрано перший параметр -->
<select v-model="selected">
  <option value="абв">АБВ</option>
</select>

Але іноді нам може знадобитися прив'язати значення до динамічної властивості поточного активного екземпляра. Для цього ми можемо використати v-bind. Крім того, використання v-bind дозволяє прив'язати вхідне значення до нерядкових значень.

Прапорець

template
<input
  type="checkbox"
  v-model="toggle"
  true-value="так"
  false-value="ні" />

true-value і false-value — це специфічні атрибути Vue, які працюють лише з v-model. Тут значення властивості toggle буде встановлено на 'так', якщо прапорець позначено, і встановлено на 'ні', якщо не позначено. Ви також можете прив'язати їх до динамічних значень за допомогою v-bind:

template
<input
  type="checkbox"
  v-model="toggle"
  :true-value="dynamicTrueValue"
  :false-value="dynamicFalseValue" />

Підказка

Атрибути true-value і false-value не впливають на атрибут value вхідних даних, оскільки браузери не включають непозначені поля в результівне значення форм. Щоб гарантувати, що у формі подано одне з двох значень (наприклад, «так» або «ні»), замість цього використовуйте радіокнопку.

Радіокнопка

template
<input type="radio" v-model="pick" value="перший" />
<input type="radio" v-model="pick" value="другий" />

pick матиме значення перший, коли обрано першу радіокнопку, і значення другий, коли другу.

Параметри полів вибору

template
<select v-model="selected">
  <!-- вбудований літерал об’єкта -->
  <option :value="{ number: 123 }">123</option>
</select>

v-model також підтримує прив'язування значень нерядкових значень! У наведеному вище прикладі, коли вибрано параметр, selected буде встановлено на значення літералу об'єкта { number: 123 }.

Модифікатори

.lazy

За промовчанням v-model синхронізує введене значення з даними після кожної події input (за винятком введення IME, як вказано вище). Ви можете додати модифікатор lazy для синхронізації після подій change:

template
<!-- синхронізовано після "change" замість "input" -->
<input v-model.lazy="msg" />

.number

Якщо ви хочете, щоб введені користувачем дані автоматично перетворювалися на числові, ви можете додати модифікатор number до своїх керованих полів v-model:

template
<input v-model.number="age" />

Якщо значення не можна проаналізувати за допомогою parseFloat(), замість нього використовується оригінальне значення.

Модифікатор number застосовується автоматично, якщо поле має type="number".

.trim

Якщо ви хочете, щоб пробіли у введених користувачами обрізалися автоматично, ви можете додати модифікатор trim до своїх введених даних, керованих v-model:

template
<input v-model.trim="msg" />

v-model з компонентами

Якщо ви ще не знайомі з компонентами Vue, можете поки що пропустити це.

Вбудовані типи введення HTML не завжди відповідають вашим потребам. На щастя, компоненти Vue дозволяють створювати багаторазові поля введення з повністю налаштованою поведінкою. Ці поля працюють навіть з v-model! Щоб дізнатися більше, прочитайте про використання з v-model у гіді по компонентах.

Прив'язування елементів форми has loaded