Компонент: стили
В статье о шаблоне мы упоминали возможность применения динамических атрибутов class и style, передавая в них JavaScript-выражения. Здесь мы подробнее разберём работу с этими атрибутами, а также рассмотрим блок style внутри компонента.
В шаблоне допускается одновременное использование статических и динамических классов и стилей:
<a
class="link"
:class="dynamicClass"
style="color: blue;"
:style="dynamicStyle"
href="/"
>
Link text
</a>
Такая запись полностью корректна. К ссылке будут применены как динамические, так и статические классы и стили.
Динамические class и style принимают массивы и объекты. Рассмотрим примеры.
С использованием массивов:
<a
class="link"
:class="[myClass1, myClass2, myClass3]"
style="color: blue;"
:style="[myStyle1, myStyle2, myStyle3]"
href="/"
>
Link text
</a>
Каждый из этих классов может быть параметром компонента, свойством, вычисляемым свойством или методом (в последнем случае его необходимо вызывать с круглыми скобками).
С использованием объектов:
<a
class="link"
:class="{ active: isActive, visited: isVisited, 'admin-class': userRole === 'admin' }"
style="color: blue;"
:style="{ color: computedColor }"
href="/"
>
Link text
</a>
Смешанный вариант. Объекты в массиве:
<a
class="link"
:class="[{ active: isActive }, myClass1, myClass2]"
style="color: blue;"
:style="[{ color: computedColor }, myStyle1, myStyle2]"
href="/"
>
Link text
</a>
Это позволяет выстраивать сложные условия назначения классов и стилей, делая стилизацию компонента по-настоящему динамической.
Блок стилей в компоненте
Мы разобрали различные способы работы с классами и стилями в шаблоне. Теперь перейдём к блоку стилей в компоненте. В простейшем виде это обычный блок:
<style>
.some-class {
display: flex;
justify-content: center;
...
}
</style>
Таких блоков в компоненте может быть несколько. К примеру, в одном блоке располагаются основные стили, а во втором — классы, связанные с анимацией. Это зачастую удобно.
Тег <style> поддерживает атрибуты scoped и module, которые служат для ограничения области видимости стилей.
По умолчанию стили являются глобальными. Это значит, что если в других компонентах используются те же классы, стили применятся и к ним. Обычно это нежелательно, и мы хотим ограничить действие стилей только текущим компонентом. Добиться этого можно с помощью атрибута scoped:
<template>
<div class="some-class">...</div>
</template>
<style scoped>
.some-class {
display: flex;
justify-content: center;
...
}
</style>
При компиляции будет сгенерирован уникальный дата-атрибут, применяемый при назначении стилей. Это обеспечивается за счёт PostCSS. Результат будет выглядеть следующим образом:
<template>
<div class="some-class" data-v-f3f3eg9 >...</div>
</template>
<style>
.some-class[data-v-f3f3eg9] {
display: flex;
justify-content: center;
...
}
</style>
Допускается наличие блоков style как с атрибутом scoped, так и без него в рамках одного компонента.
В проектах мы будем применять scoped-стили. Для ограничения видимости стилей также можно использовать CSS-модули. Подробнее о них можно узнать по ссылке.
Благодаря scoped стили родительского компонента не затрагивают содержимое дочерних компонентов. Тем не менее иногда бывает необходимо задать определённые стили для дочернего компонента из родительского — для этого применяются глубокие селекторы.
Глубокие селекторы
Если нужно, чтобы селектор в scoped-стилях проникал в дочерние компоненты, можно воспользоваться псевдоклассом :deep:
<template>
<div class="parent">
<child-component />
</div>
</template>
<style scoped>
.parent :deep(.some-class) {
display: flex;
justify-content: center;
...
}
</style>
Таким образом вы получите доступ к классу .some-class дочернего компонента и рекурсивно ко всем его вложенным дочерним компонентам.
Стили с ограниченной областью
По умолчанию CSS-стили не распространяются на контент, размещённый в слотах (slots). Чтобы изменить это поведение, используется атрибут :slotted.
<style scoped>
:slotted(.some-class) {
display: flex;
justify-content: center;
...
}
Глобальные селекторы
Иногда требуется применить CSS-свойства на глобальном уровне. Для этого можно воспользоваться атрибутом global.
<style scoped>
:global(.some-class) {
display: flex;
justify-content: center;
...
}
Использование локальных и глобальных стилей в одном компоненте
Vue допускает наличие двух блоков стилей в одном компоненте — для локальных и глобальных правил.
<style>
/* глобальные стили */
</style>
<style scoped>
/* локальные стили */
</style>
Атрибут lang
Тег style поддерживает атрибут lang. По умолчанию используется CSS, но можно подключить и препроцессор:
<template>
<div class="some-class">...</div>
</template>
<style scoped lang="stylus">
.some-class
display flex
justify-content center
...
</style>
В данном примере используется Stylus. Помимо него, вы можете применять такие препроцессоры, как Sass, SCSS, LESS.
В наших проектах мы используем SCSS.
Использование стилей в учебном проекте
В учебном проекте общие стили расположены в директории src/assets/scss.
В корневом компоненте App.vue рекомендуется импортировать файл src/assets/scss/app.scss, содержащий глобальные стили приложения.
В компонентах нередко потребуется импортировать два файла:
src/assets/scss/ds-system/ds.scss— правила дизайн-системы: типографика и цвета;src/assets/scss/mixins/mixins.scss— набор примесей (миксинов), преимущественно для позиционирования элементов.
Предполагается, что вы уже знакомы с основами работы с Sass/SCSS. Если нет, изучите руководство.