Привязка классов и стилей
Внешний вид элемента часто зависит от данных: выполненная задача зачёркнута, активная кнопка фильтра выделена. Для этого у v-bind есть особый режим для атрибутов class и style — им можно передать объект или массив.
Объект классов
<!-- src/App.vue -->
<script setup>
import { ref } from 'vue'
const todos = ref([
{ id: 1, text: 'Купить хлеб', done: true },
{ id: 2, text: 'Позвонить Анне', done: false },
])
</script>
<template>
<ul>
<li
v-for="todo in todos"
:key="todo.id"
:class="{ done: todo.done }"
@click="todo.done = !todo.done"
>
{{ todo.text }}
</li>
</ul>
</template>
<style scoped>
.done {
text-decoration: line-through;
color: #999;
}
</style>Первая задача на странице зачёркнута и серая. Клик по задаче переключает поле done, и класс done появляется или исчезает. Ключ объекта — имя класса, значение — условие.
Обычный и динамический класс вместе
Статический class и привязанный :class объединяются:
<li class="todo" :class="{ done: todo.done, urgent: todo.urgent }">
{{ todo.text }}
</li>У выполненной срочной задачи будет class="todo done urgent", у обычной — только class="todo". Имя класса с дефисом берите в кавычки: { 'is-active': active }.
Массив классов
Массив удобен, когда имя класса хранится в переменной:
<script setup>
import { ref } from 'vue'
const filter = ref('active')
</script>
<template>
<button :class="['filter', filter === 'active' ? 'selected' : '']">
Активные
</button>
</template>Кнопка получит классы filter selected, пока выбран фильтр active.
Привязка стилей
:style принимает объект CSS-свойств. Имена пишутся в camelCase, как в element.style из учебника:
<script setup>
import { ref } from 'vue'
const progress = ref(40)
</script>
<template>
<div class="bar">
<div :style="{ width: progress + '%', backgroundColor: '#42b883' }"></div>
</div>
</template>Внутренний блок займёт 40% ширины полосы и окрасится в зелёный. Если progress изменится, ширина обновится сама — так делают полосу выполнения задач.
Что выбрать
| Задача | Способ |
|---|---|
| Включить класс по условию | :class с объектом |
| Класс из переменной | :class с массивом |
| Значение, вычисленное в коде, — ширина, цвет | :style |
| Постоянное оформление | Обычный CSS в style scoped |
Предпочитайте классы: оформление остаётся в CSS, а шаблон только включает его.
Частая ошибка
Передать в :class строку с условием:
<li :class="todo.done ? done : ''">Здесь done без кавычек — это переменная, а не имя класса, и она не определена. Правильно :class="todo.done ? 'done' : ''" или проще — объектом: :class="{ done: todo.done }".