CSS-in-JS — это подход, при котором стили описываются непосредственно в JavaScript-коде компонентов. Такой метод позволяет тесно связывать стили с логикой компонентов, обеспечивать динамическое формирование CSS и управлять областью видимости стилей без глобальных конфликтов. Во Vue.js этот подход реализуется через несколько инструментов и методик, включая scoped стили, CSS Modules и сторонние библиотеки.
Vue поддерживает встроенную функциональность scoped стилей, которая
позволяет ограничивать действия CSS конкретным компонентом. Для этого
используется атрибут scoped в
<style>:
<template>
<div class="card">
<h2>{{ title }}</h2>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
props: {
title: String,
content: String
}
}
</script>
<style scoped>
.card {
border: 1px solid #ccc;
padding: 16px;
border-radius: 8px;
}
.card h2 {
color: #333;
}
</style>
Особенности scoped стилей:
CSS Modules позволяют создавать локальные CSS-классы с уникальными
именами, обеспечивая изоляцию стилей. В Vue для этого достаточно
включить соответствующую опцию в <style>:
<template>
<div :class="$style.card">
<h2 :class="$style.title">{{ title }}</h2>
</div>
</template>
<script>
export default {
props: {
title: String
}
}
</script>
<style module>
.card {
border: 2px solid #007BFF;
padding: 12px;
border-radius: 6px;
}
.title {
font-weight: bold;
color: #007BFF;
}
</style>
Преимущества CSS Modules:
Существуют сторонние библиотеки, полностью реализующие CSS-in-JS в Vue:
import styled from 'vue-styled-components';
const Button = styled.button`
background-color: #42b983;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
&:hover {
background-color: #369870;
}
`;
export default {
components: { Button }
}
@emotion/css:import { css } from '@emotion/css';
export default {
setup() {
const buttonClass = css`
background-color: #ff6f61;
color: #fff;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: #ff4c3b;
}
`;
return { buttonClass };
}
}
<template>
<button :class="buttonClass">Нажми меня</button>
</template>
Особенности библиотек CSS-in-JS:
В Vue CSS-in-JS позволяет связывать свойства стиля с реактивными данными. Например:
<template>
<div :style="cardStyle">
{{ message }}
</div>
</template>
<script>
import { reactive, computed } from 'vue';
export default {
setup() {
const state = reactive({ highlighted: false });
const cardStyle = computed(() => ({
backgroundColor: state.highlighted ? '#ffeebb' : '#ffffff',
border: '1px solid #ccc',
padding: '16px',
borderRadius: '8px'
}));
return { cardStyle, state };
}
}
</script>
Преимущества динамических стилей:
CSS-in-JS решения легко интегрируются с глобальными состояниями, управляемыми Vuex или Composition API. Например, можно создать общую тему и применять её в различных компонентах через реактивные свойства:
// theme.js
import { reactive } from 'vue';
export const theme = reactive({
primaryColor: '#42b983',
secondaryColor: '#35495e'
});
<template>
<button :style="{ backgroundColor: theme.primaryColor }">Кнопка</button>
</template>
<script>
import { theme } from './theme';
export default {
setup() {
return { theme };
}
}
</script>
Таким образом, любые изменения в theme автоматически
обновят стили во всех компонентах, использующих эти переменные.
CSS-in-JS в Vue.js сочетает удобство реактивного управления состоянием и гибкость работы со стилями, что делает его мощным инструментом для современных веб-приложений.