События, v-model, классы и стили

Закрываем основы шаблонов: реагируем на действия пользователя через @, связываем формы двусторонне через v-model и динамически меняем классы и стили.

v-on (краткая запись @) навешивает обработчик события. v-model создаёт двустороннюю связь между полем формы и данными.

Обработка событий: v-on и @

Директива v-on:click (или коротко @click) выполняет выражение или вызывает метод при событии:

<template>
  <p>Счёт: {{ count }}</p>
  <button @click="count++">+1</button>
  <button @click="reset">Сброс</button>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function reset() {
  count.value = 0
}
</script>

Можно писать выражение прямо в шаблоне (count++) или вынести в функцию (reset). Часто нужны модификаторы: @submit.prevent отменяет перезагрузку страницы формой, @click.stop останавливает всплытие.

Двусторонняя привязка: v-model

Чтобы синхронизировать поле ввода с данными, обычно нужно и читать значение, и записывать его обратно. v-model делает оба направления сразу:

<template>
  <input v-model="name" placeholder="Ваше имя">
  <p>Привет, {{ name || 'гость' }}!</p>
</template>

<script setup>
import { ref } from 'vue'
const name = ref('')
</script>

Печатаете в поле — name обновляется и абзац ниже меняется мгновенно. Меняете name в коде — обновляется поле. v-model работает с <input>, <textarea>, <select> и чекбоксами.

Под капотом v-model

v-model на <input> — это сокращение: привязка :value плюс обработчик события input. Разворот эквивалентен такому коду:

<input :value="name" @input="name = $event.target.value">

Понимать это полезно: v-model — не магия, а удобная упаковка привязки и события.

Динамические классы: :class

Привязка :class умеет принимать объект «класс → условие»: класс добавится, только если значение истинно. Это удобнее, чем строить строку классов вручную:

<template>
  <p :class="{ active: isActive, error: hasError }">Статус</p>
  <button @click="isActive = !isActive">Переключить</button>
</template>

<script setup>
import { ref } from 'vue'
const isActive = ref(true)
const hasError = ref(false)
</script>

Динамические стили: :style

Привязка :style принимает объект со свойствами CSS (имена в camelCase):

<template>
  <div :style="{ color: textColor, fontSize: size + 'px' }">
    Текст
  </div>
</template>

<script setup>
import { ref } from 'vue'
const textColor = ref('teal')
const size = ref(20)
</script>

Шпаргалка директив

ЗаписьНазначение
@clickобработчик события (краткая форма v-on)
v-modelдвусторонняя привязка поля формы
:class="{ a: cond }"класс a при истинном cond
:style="{ color: c }"динамические inline-стили объектом

Итог

  • @событие (краткая форма v-on) навешивает обработчик; есть модификаторы .prevent, .stop.
  • v-model — двусторонняя связь поля и данных; под капотом это :value + @input.
  • :class="{ имя: условие }" добавляет класс по условию.
  • :style принимает объект CSS-свойств (camelCase).
Проверьте себя
1. Какая краткая запись у директивы v-on:click?
A:click
B#click
C@click
Dv-click
2. Что делает v-model на элементе <input>?
AТолько читает значение поля
BСоздаёт двустороннюю связь: поле обновляет данные, и данные обновляют поле
CЗапрещает редактировать поле
DВалидирует ввод по маске
3. Как с помощью :class добавить класс active только при истинном isActive?
A:class="active: isActive"
B:class="{ active: isActive }"
Cclass="{{ isActive }}"
D:class="isActive.active"
Поддержать проект