Styled-components — это подход к стилизации компонентов, позволяющий инкапсулировать CSS прямо внутри компонентов JavaScript. В Vue.js такой подход реализуется через возможности scoped-стилей и библиотек, интегрирующих CSS-in-JS, что позволяет создавать динамические и модульные стили без утечки в глобальную область.
В Vue.js нет встроенной поддержки styled-components, как в React, но существуют альтернативные решения:
Пример использования vue-styled-components:
import styled from 'vue-styled-components';
const buttonProps = { primary: Boolean };
const StyledButton = styled('button', buttonProps)`
background-color: ${props => (props.primary ? 'blue' : 'gray')};
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
`;
export default {
components: { StyledButton },
template: `<StyledButton :primary="true">Кнопка</StyledButton>`
};
Здесь ключевым моментом является передача пропсов в styled-компонент, что позволяет менять стиль динамически в зависимости от состояния.
Styled-components позволяют использовать любые данные для изменения CSS. В Vue.js это особенно полезно для реактивных состояний.
const Container = styled('div', { size: String })`
width: ${props => (props.size === 'large' ? '500px' : '300px')};
height: 200px;
background-color: lightcoral;
`;
export default {
components: { Container },
data() {
return { boxSize: 'large' };
},
template: `<Container :size="boxSize"></Container>`
};
Здесь props.size управляет шириной блока в зависимости от значения реактивного свойства.
В крупных приложениях важно централизованно управлять цветовой схемой
и другими стилевыми параметрами. Пример с
vue-styled-components:
import styled, { ThemeProvider } from 'vue-styled-components';
const theme = {
primaryColor: 'blue',
secondaryColor: 'green'
};
const Title = styled.h1`
color: ${props => props.theme.primaryColor};
`;
export default {
components: { Title, ThemeProvider },
template: `
<ThemeProvider :theme="theme">
<Title>Заголовок</Title>
</ThemeProvider>
`,
data() {
return { theme };
}
};
Использование ThemeProvider обеспечивает доступ к глобальной теме для всех вложенных компонентов без необходимости вручную передавать пропсы.
Если подключать внешние библиотеки нежелательно, Vue.js позволяет
инкапсулировать стили через <style scoped>:
<template>
<button :class="{ primary: isPrimary }">Нажми меня</button>
</template>
<script>
export default {
data() {
return { isPrimary: true };
}
};
</script>
<style scoped>
button {
color: white;
padding: 10px 20px;
border-radius: 5px;
}
button.primary {
background-color: blue;
}
button:not(.primary) {
background-color: gray;
}
</style>
Хотя это не полноценный CSS-in-JS, такой подход обеспечивает локальные стили и возможность динамического изменения через привязку классов.
Использование Composition API позволяет создавать реактивные стили на основе состояния:
import { ref } from 'vue';
import styled from 'vue-styled-components';
const Box = styled('div', { color: String })`
width: 100px;
height: 100px;
background-color: ${props => props.color};
`;
export default {
setup() {
const color = ref('red');
return { color };
},
components: { Box },
template: `<Box :color="color"></Box>`
};
Здесь реактивная переменная color автоматически обновляет стиль компонента при изменении значения.
Этот подход позволяет создавать масштабируемые Vue-приложения с чистой архитектурой, гибкой темизацией и полностью инкапсулированными стилями, сохраняя преимущества реактивного фреймворка.