Работа с классами и стилями
Часто возникает необходимость динамически изменять CSS-классы и inline-стили элементов в зависимости от состояния приложения. Поскольку и то и другое атрибуты, мы можем использовать v-bind: необходимо лишь вычислить итоговую строку при помощи выражения. Впрочем, заниматься конкатенацией строк неудобно, это может привести к ошибкам. К счастью, Vue предоставляет дополнительные возможности директивы v-bind для работы с class и style. Эти атрибуты кроме строковых значений могут принимать массивы или объекты.
Связывание CSS-классов
Объектный синтаксис
Для динамической установки или удаления CSS-классов можно передавать объект в директиву :class (сокращение для v-bind:class):
<div :class="{ active: isActive }"></div>
1
Запись выше означает, что наличие класса active будет определяться истинностью (opens new window) параметра isActive.
Таким образом можно управлять несколькими классами, добавляя в объект другие поля. Кроме того, :class можно использовать совместно с обычным атрибутом class:
<div
:class="{ active: isActive, 'text-danger': hasError }"
></div>
1
2
3
4
При использовании таких данных:
data: {
isActive: true,
hasError: false
}
1
2
3
4
В результате получится:
<div></div>
1
Список классов элемента обновится при изменении или hasError. Например, если hasError станет true, то значением атрибута class будет "static active text-danger".
Используемый объект необязательно указывать прямо в шаблоне:
<div :class="classObject"></div>
1
data() {
return {
classObject: {
active: true,
'text-danger': false
}
}
}
1
2
3
4
5
6
7
8
Результат будет таким же.
Можно также использовать и вычисляемые свойства, которые возвращают объект — это очень распространённый и мощный приём:
<div :class="classObject"></div>
1
data() {
return {
isActive: true,
error: null
}
},
computed: {
classObject() {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Синтаксис с массивом
В :class можно передавать и массив:
<div :class="[activeClass, errorClass]"></div>
1
data() {
return {
activeClass: 'active',
errorClass: 'text-danger'
}
}
1
2
3
4
5
6
В результате получим:
<div></div>
1
Для переключения классов в массиве, в зависимости от некоторого условия, можно использовать условный оператор в тернарной форме:
<div :class="[isActive ? activeClass : '', errorClass]"></div>
1
В этом случае errorClass будет применён к элементу всегда, но activeClass — только в случае истинности isActive.
Однако, такая запись становится слегка громоздкой, особенно если есть несколько классов, задаваемых по условию. Но можно использовать и смешанный синтаксис:
<div :class="[{ active: isActive }, errorClass]"></div>
1
Использование с компонентами
Эта секция предполагает знакомство с компонентами Vue. Вы можете спокойно пропустить её сейчас и вернуться позднее.
При использовании атрибута class на пользовательском компоненте с одним корневым элементом, классы будут добавлены к этому корневому элементу. Собственные классы элемента при этом не будут потеряны.
Возьмём, к примеру, такой компонент:
const app = Vue.createApp({})
app.component('my-component', {
template: '<p>Привет</p>'
})
1
2
3
4
5
Если указать дополнительные классы на компоненте:
<div> <my-component></my-component> </div>
1
2
3
В результате отрисовки получим:
<p>Привет</p>
1
То же самое справедливо для связывания классов с данными:
<my-component :class="{ active: isActive }"></my-component>
1
Если isActive истинно, результирующий HTML будет:
<p>Привет</p>
1
Если у компонента несколько корневых элементов, то потребуется определить который из них получит эти классы.
Это реализуется добавлением свойства $attrs на элемент:
<div> <my-component></my-component> </div>
1
2
3
const app = Vue.createApp({})
app.component('my-component', {
template: `
<p :class="$attrs.class">Привет!</p>
<span>Это дочерний компонент</span>
`
})
1
2
3
4
5
7
8
Подробнее о наследовании атрибутов в компонентах можно узнать в разделе Non-Prop Attributes.
Связывание inline-стилей
Объектный синтаксис
Объектная запись для :style выглядит почти как CSS, хотя, на самом деле, это объект JavaScript. Для указания свойств CSS можно применять как camelCase, так и kebab-case (не забывайте про кавычки при использовании kebab-case):
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
1
data() {
return {
activeColor: 'red',
fontSize: 30
}
}
1
2
3
4
5
6
Можно выносить объект стилей из шаблона, чтобы сделать код чище:
<div :style="styleObject"></div>
1
data() {
return {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
}
1
2
3
4
5
6
7
8
Можно использовать и вычисляемые свойства, возвращающие объекты стилей.
Синтаксис с массивом
Запись :style с массивом позволяет применить несколько объектов стилей к одному и тому же элементу:
<div :style="[baseStyles, overridingStyles]"></div>
1
Автоматические префиксы
При использовании в :style свойств CSS, требующих указания вендорных префиксов (opens new window), Vue автоматически определит это и добавит подходящие префиксы к применяемым стилям.
Множественные значения
Можно предоставить массив из нескольких (префиксных) значений для свойства style, например:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
1
Это приведёт к отображению последнего значения в массиве, поддерживаемого браузером. В этом примере он будет отображать display: flex для браузеров, которые поддерживают flexbox без префиксов.
Поиск DOM элементов по тегам и классам
В предыдущем уроке мы с вами рассмотрели метод document.
getElementById, который позволяет нам находить уникальный елемент и потом мы можем менять его свойства.
Как еще можно находить елементы на странице? Очень часто нам приходится находить не один елемент, а массив елементов на странице.
Давайте добавим в наш html 4 дива
<body>
<p>
Some text
</p>
<div>Div 1</div>
<div>Div 2</div>
<div>Div 3</div>
<div>Div 4</div>
<button>Change</button>
</body>
Теперь мы можем использовать специальную функцию getElementsByTagName, чтобы найти эти елементы по тегу div.
function changeColor () {
var elements = document.getElementsByTagName('div')
console.log(elements)
}
Как мы видим в консоли, у нас вывелся массив из 4 елементов. И если мы хотим поменять свойство первого, то мы должны обратиться к елементу по индексу, как мы делали в уроке «Массивы в Javascript». Ссылку на него я оставлю в тексте видео.
Обращаясь к елементу по индексу мы получаем обычный DOM елемент и можем менять его свойста.
function changeColor () {
var elements = document.getElementsByTagName('div')
console.log(elements)
elements[0].style.color = 'red'
}
Если мы посмотрим в браузер, то елемент у нас стал красным.
Что же делать если елементов много и мы хотим поменять их все? В этом нам поможет цикл for. Циклы вы также можете посмотреть в уроке «Циклы в Javascript».
Давайте напишем цикл от нуля до длины массива. Длину массива можно узнать с помощью свойста length. И внутри цикла поменяем цвет каждого елемента на красный.
function changeColor () {
var elements = document.getElementsByTagName('div')
console.log(elements)
for(var i = 0; i < elements.length; i++) {
elements[i].style.color = 'red'
}
}
Если мы посмотрим в браузер, то цвет поменялся у всех елементов.
Но по тегу обращаться к елементам не всегда удобно, так как тегов мало, а елементов, которые вы хотите модифицировать на странице много и их нужно как-то уникально различать. Именно поэтому большинство елементов всегда ищут по классу.
Давайте перепишем этот же код используя классы. Добавим класс к всем div елементам.
<body> <div>Div 1</div> <div>Div 2</div> <div>Div 3</div> <div>Div 4</div> <button>Change</button> </body>
Теперь давайте заменим метод getElementsByTagName на getElementsByClassName.
function changeColor () {
var elements = document.getElementsByClassName('article')
console.log(elements)
for(var i = 0; i < elements.length; i++) {
elements[i].style.color = 'red'
}
}
Как мы видим в браузере, цвета все так же меняются, хотя елементы мы ищем уже по классу.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео и я обязательно на них отвечу.
Как динамически добавить имя класса в Vue
Возможность добавить динамическое имя класса к вашему компоненту действительно полезна.
Это упрощает создание пользовательских тем, добавление классов на основе состояния компонента, а также создание различных вариантов компонента, зависящих от стиля.
Добавить имя динамического класса так же просто, как добавить свойство :class="classname" к вашему компоненту. Какое бы имя класса ни оценивало, оно будет именем класса, добавляемым к вашему компоненту.
Конечно, есть еще и многое другое, что мы можем сделать здесь с помощью динамических классов в Vue.
В этой статье мы расскажем о многом:
- Использование статических и динамических классов в Vue
- Как мы можем использовать регулярные выражения Javascript для вычисления нашего класса
- Синтаксис массива для имен динамических классов
- Синтаксис объекта (для большего разнообразия!)
- Генерация имен классов на лету
- Как использовать имена динамических классов в пользовательских компонентах
Не только это, но в конце я покажу вам простой шаблон для использования вычисляемых свойств, чтобы помочь очистить ваши шаблоны. Это пригодится, когда вы начнете везде использовать динамические имена классов!
В Vue мы можем добавлять к нашим компонентам как статические, так и динамические классы.
Статические классы — это скучные классы, которые никогда не меняются и всегда будут присутствовать в вашем компоненте. С другой стороны, динамических классов — это те, которые мы можем добавлять и удалять в нашем приложении.
Если бы мы хотели добавить статический класс, это было бы точно так же, как в обычном HTML:
<диапазон>
Вот как вы добавляете статические классы в Vue.
Динамические классы очень похожи, но мы должны использовать специальный синтаксис свойств Vue, v-bind , чтобы связать выражение Javascript с нашим классом:
Вот как вы добавляете статические классы в Vue.
шаблон> Вы заметите, что нам пришлось добавить дополнительные кавычки вокруг имени нашего динамического класса.
Это связано с тем, что синтаксис v-bind принимает все, что мы передаем, как значение Javascript.
Добавление кавычек гарантирует, что Vue будет рассматривать его как строку.
Vue также имеет сокращенный синтаксис для v-bind :
Вот как вы добавляете статические классы в Vue.
Что действительно здорово, так это то, что вы даже можете иметь как статические, так и динамические классы в одном и том же компоненте.
Это позволит вам иметь несколько статических классов для вещей, которые, как вы знаете, не изменятся, таких как позиционирование и макет, а также динамические классы для вашей темы:
<промежуток
:класс="тема"
>
Вот как вы добавляете статические классы в Vue.
экспорт по умолчанию {
данные() {
возвращаться {
тема: 'синяя тема',
};
}
}; .синяя тема {
цвет: темно-синий;
фон: белый;
} В данном случае тема — это переменная, которая содержит имя класса, который мы применим (помните, что здесь он обрабатывается как Javascript).
Имена условных классов
Так как v-bind будет принимать любое выражение Javascript, мы можем делать с ним кое-что очень классное.
Мне больше всего нравится использовать тернарии внутри шаблона, что, как правило, довольно чисто и читабельно.
Но мы не будем об этом.
Существует множество различных способов условной привязки классов в Vue, и их стоит изучить.
Использование синтаксиса массива
Если есть много разных классов, которые вы хотите добавить динамически, вы можете использовать массивы или объекты. Оба варианта полезны, но сначала мы рассмотрим массивы.
Поскольку мы просто оцениваем выражение JavaScript, вы можете комбинировать выражения, которые мы только что изучили, с синтаксисом массива:
<промежуток
:класс="[
шрифтТема,
темный режим ? 'темная тема' : 'светлая тема',
]"
>
Вот как вы добавляете динамические классы в Vue.
шаблон> Что здесь происходит?
Мы используем массив для установки двух имен динамических классов для этого элемента.
Значение fontTheme — это имя класса, которое изменит внешний вид наших шрифтов.
В нашем предыдущем примере мы по-прежнему можем переключаться между светлой и темной темами, используя нашу переменную darkMode .
Использование синтаксиса объекта
Мы даже можем использовать объект для определения списка динамических классов, что дает нам больше гибкости.
Для любой пары ключ/значение, где значение равно true , он применит ключ в качестве имени класса.
Давайте рассмотрим пример синтаксиса объекта:
<промежуток
:класс="{
«темная тема»: darkMode,
'светлая тема': !darkMode,
]"
>
Вот как вы добавляете динамические классы в Vue.
Наш объект содержит два ключа, темная тема и светлая тема . Подобно логике, которую мы реализовали ранее, мы хотим переключаться между этими темами на основе значения 9.
0008 темный режим .
Когда darkMode равно true , он применит dark-theme в качестве имени динамического класса к нашему элементу. Но светлая тема не будет применена, потому что !darkMode будет оцениваться как false .
Противоположное происходит, когда darkMode имеет значение false. Мы получаем light-theme в качестве динамического имени класса вместо dark-theme .
Общепринято использовать тире или дефисы в именах классов CSS. Но чтобы записать ключи объекта с тире в Javascript, нам нужно заключить его в кавычки, чтобы он стал строкой.
Теперь мы рассмотрели основы динамического добавления классов в компоненты Vue.
Как это сделать с нашими собственными компонентами?
Использование с пользовательскими компонентами
Допустим, у нас есть пользовательский компонент, который мы используем в нашем приложении:
<Список фильмов
:movies="фильмы"
:жанр="жанр"
/>
Если мы хотим динамически добавить класс, который изменит тему, что мы будем делать?
На самом деле это очень просто.
Мы просто добавляем свойство :class , как и раньше!
<шаблон>
<Список фильмов
:movies="фильмы"
:жанр="жанр"
:class="darkMode ? 'темная тема' : 'светлая тема'"
/>
Причина, по которой это работает, заключается в том, что Vue установит класс на корневой элемент MovieList напрямую.
Когда вы устанавливаете реквизиты для компонента, Vue сравнивает эти реквизиты с тем, что компонент указал в своих реквизит раздел. Если есть совпадение, он передаст его как обычную опору. В противном случае Vue добавит его в корневой элемент DOM.
Здесь, поскольку MovieList не указал свойство класса , Vue знает, что он должен установить его для корневого элемента.
Есть и более продвинутые вещи, которые мы можем делать с динамическими именами классов…
Генерация имен классов на лету
Мы видели много разных способов динамического добавить или удалить имен классов.
А как насчет динамического создания самого имени класса?
Допустим, у вас есть компонент Button с 20 различными стилями CSS для всех ваших различных типов кнопок.
Сколько вариаций!
Вы, вероятно, не хотите тратить весь день на выписывание каждого из них вместе с логикой включения и выключения. Это также будет неприятным беспорядком, когда придет время обновить список!
Вместо этого мы будем динамически генерировать имя класса , который мы хотим применить.
Простая версия этого, которую вы уже видели:
<шаблон>
<промежуток
:класс="тема"
>
Вот как вы добавляете статические классы в Vue.
экспорт по умолчанию {
данные() {
возвращаться {
тема: 'синяя тема',
};
}
}; .синяя тема {
цвет: темно-синий;
фон: белый;
} Мы можем установить переменную, содержащую строку любого имени класса, которое мы хотим.
Если бы мы хотели сделать это для нашего компонента Button , мы могли бы сделать что-то простое, например:
<кнопка
@click="$emit('щелчок')"
:класс="тема"
>
{{ текст }}
кнопка>
экспорт по умолчанию {
реквизит: {
тема: {
тип: Строка,
по умолчанию: 'по умолчанию',
}
}
}; .по умолчанию {}
.начальный {}
.danger {} Теперь любой, кто использует компонент Button , может просто установить тема поддерживает любую тему, которую они хотят использовать.
Если ничего не установить, будет добавлен класс .default .
Если установить его на primary , он добавит класс .primary .
Приведение в порядок вещей с помощью вычисляемых реквизитов
Со временем выражения в нашем шаблоне станут слишком сложными, и он станет очень запутанным и трудным для понимания.
К счастью, у нас есть простое решение.
Если мы преобразуем наши выражения в вычисляемые свойства, мы можем переместить больше логики из шаблона и очистить его:
<шаблон>
<Список фильмов
:movies="фильмы"
:жанр="жанр"
:класс="класс"
/>
экспорт по умолчанию {
вычислено: {
сорт() {
вернуть темный режим? «темная тема» : «светлая тема»;
}
}
}; Это не только намного легче читать, но также проще добавлять новые функции и проводить рефакторинг в будущем.
Этот паттерн — перемещение объектов из шаблона в вычисляемые свойства — работает со всеми видами объектов. Это один из лучших способов очистить ваши компоненты Vue!
Удаление и добавление имен классов из элементов с использованием чистого JavaScript – clubmate.fi
Удаление и добавление имен классов из элементов с использованием чистого JavaScript можно удалить или добавить с помощью
classList , или они могут быть изменены напрямую с помощью свойства className .
Использование метода classList
classList — довольно умная и самая современная система управления именами классов CSS в элементах через JavaScript.
Удалить имена классов
Вот как удалить одно имя класса :
const element = document.getElementById('foo')
element.classList.remove('bar') Несколько имен классов можно удалить, передав больше параметров методу remove :
element.classList.remove('bar', 'baz') Или удалить данное имя класса из всех элементов одновременно ; в этом примере я удаляю класс .open из элемента аккордеона:
const AccordionItems = [...document.getElementsByClassNme('accordion-item')]
аккордеонItems.forEach(accordionItem => {
аккордеонItem.remove('открыть')
}) Добавление имен классов
Добавление имен классов не сильно отличается:
const element = document.getElementById('foo') element.classList.add('my-class')
Все методы classList
Я думаю, что remove и add являются наиболее часто используемыми методами класса classList, но вот все они, с краткими примерами:
-
remove() - Удаляет класс из списка классов элемента. Если класс не существует в списке классов элемента, он не выдаст ошибку или исключение.
-
add() - Добавляет класс в список классов элемента. Если класс уже существует в списке классов элемента, он не будет добавлен снова.
-
toggle() - Переключает существование класса в списке классов элемента. Очень полезно при обработке кликов, например:
const button = document.getElementById('button') button.addEventListener('щелчок', событие => { event.target.classList.toggle('видимый') }) -
contains() - Проверяет, содержит ли список классов элемента определенный класс
if (element.
classList.contains('my-class')) {
// Делаем что-то...
} еще {
// Делаем другие вещи...
}
Поддержка браузера
classList поддерживается, начиная с IE10, Opera Mini не поддерживается. См. таблицу поддержки на сайте caniuse.com
Свойство className
В HTML мы можем просто сказать , но в JavaScript слово «класс» является зарезервированным словом, поэтому его нужно называть className вместо:
const element = document.getElementById('foo')
element.className = 'my-class' Примечание: , который переопределяет существующий класс , следующее добавляет его к старому имени класса, это точно так же, как и любая переменная:
const element = document.getElementById('foo ')
element.className += 'my-class' Управление именами классов в NodeList
NodeList — это объект, подобный массиву, но не массив как таковой. Но цикл for на нем работает без проблем:
константный элемент = document.

getElementById('foo')
element.classList.add('my-class')
classList.contains('my-class')) {
// Делаем что-то...
} еще {
// Делаем другие вещи...
} 