CSS переменные, также известные как кастомные
свойства, позволяют хранить значения CSS в отдельных
переменных, которые можно переиспользовать в разных частях приложения. В
стандартном CSS они объявляются с помощью синтаксиса
--имя-переменной, а используются через функцию
var().
Пример объявления и использования:
:root {
--primary-color: #42b983;
--font-size-base: 16px;
}
.button {
background-color: var(--primary-color);
font-size: var(--font-size-base);
}
Переменные можно задавать на уровне глобальных
стилей (:root) или локально в
компоненте Vue, что позволяет создавать изолированные темы для отдельных
модулей.
В Vue.js переменные можно использовать как в Single File Components (SFC), так и в глобальных стилях. При использовании SFC структура выглядит следующим образом:
<template>
<div class="card">
Тема приложения
</div>
</template>
<script>
export default {
name: 'ThemeCard'
}
</script>
<style scoped>
.card {
background-color: var(--card-bg, #ffffff);
color: var(--card-text, #333333);
padding: 1rem;
border-radius: 8px;
}
</style>
Свойство scoped обеспечивает локальную область действия
стилей, но при этом переменные можно наследовать из глобального уровня
или переопределять локально.
Одно из сильных преимуществ Vue — возможность динамически
менять CSS переменные через реактивные данные. Для этого
переменные задаются на корневом элементе через style или с
помощью :style биндинга.
Пример динамического изменения темы:
<template>
<div :style="themeStyles" class="app-container">
Привет, Vue!
</div>
</template>
<script>
export default {
data() {
return {
theme: {
'--primary-color': '#42b983',
'--background-color': '#f5f5f5',
'--text-color': '#333333'
}
};
},
computed: {
themeStyles() {
return this.theme;
}
},
methods: {
switchTheme() {
this.theme['--primary-color'] = '#ff6347';
this.theme['--background-color'] = '#1e1e1e';
this.theme['--text-color'] = '#ffffff';
}
}
}
</script>
<style>
.app-container {
background-color: var(--background-color);
color: var(--text-color);
padding: 2rem;
transition: all 0.3s ease;
}
</style>
В этом примере тема меняется в реальном времени при вызове метода
switchTheme(), не требуя перезагрузки страницы или
пересборки стилей.
Для крупных приложений удобно хранить текущую тему в глобальном состоянии с помощью Vuex или Pinia, что позволяет использовать одну тему на всех компонентах.
Пример с Pinia:
// store/theme.js
import { defineStore } from 'pinia';
export const useThemeStore = defineStore('theme', {
state: () => ({
currentTheme: {
'--primary-color': '#42b983',
'--background-color': '#ffffff',
'--text-color': '#333333'
}
}),
actions: {
setDarkTheme() {
this.currentTheme = {
'--primary-color': '#ff6347',
'--background-color': '#1e1e1e',
'--text-color': '#ffffff'
};
}
}
});
<template>
<div :style="theme.currentTheme">
Темизированный компонент
</div>
</template>
<script>
import { useThemeStore } from '../store/theme';
export default {
setup() {
const theme = useThemeStore();
return { theme };
}
}
</script>
Использование глобального состояния делает смену темы предсказуемой и управляемой для всех компонентов приложения.
Для повторного использования логики темизации можно создать Vue миксин, который автоматически подключает тему к компоненту:
export const themeMixin = {
computed: {
themeStyles() {
return this.$store.state.theme.currentTheme; // или Pinia store
}
}
}
Применение в компоненте:
<template>
<div :style="themeStyles">
Контент с миксином
</div>
</template>
<script>
import { themeMixin } from '../mixins/themeMixin';
export default {
mixins: [themeMixin]
}
</script>
Такой подход снижает дублирование кода и упрощает поддержку большого приложения.
CSS переменные позволяют легко создавать настройки для пользователей. Можно хранить выбранные цвета в localStorage и при загрузке приложения применять их к корневому элементу:
const savedTheme = JSON.parse(localStorage.getItem('userTheme')) || defaultTheme;
Object.entries(savedTheme).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value);
});
Это обеспечивает сохранение пользовательской темы между сессиями без сложных перезапусков приложения.
CSS переменные совместимы с Sass или Less. В отличие от Sass-переменных, CSS переменные остаются доступными в runtime, что делает их идеальными для динамической темизации:
$primary-color: #42b983;
.button {
background-color: var(--primary-color, $primary-color);
}
Такой подход объединяет мощь препроцессора для разработки и гибкость runtime переменных для динамики интерфейса.
CSS переменные могут использоваться внутри анимаций и переходов:
:root {
--transition-duration: 0.3s;
}
.button {
background-color: var(--primary-color);
transition: background-color var(--transition-duration) ease;
}
.button:hover {
--primary-color: #ff6347;
}
Во Vue динамическое обновление переменных плавно анимируется при использовании CSS-свойств, поддерживающих переходы.
:style или глобальный
store обеспечивает гибкость и единообразие интерфейса.CSS переменные вместе с реактивностью Vue создают мощный инструмент для создания современных, гибких и настраиваемых интерфейсов.