Отказ от scoped стилей в Vue
При работе с Vue многие привычно используют , ограничивая стили текущим компонентом. Разберёмся, действительно ли это нужно, или стало устаревшей привычкой, от которой можно отказаться.
scoped в Vue
добавляет каждому селектору уникальный атрибут вроде data-v-xxxx.
Click
.button { color: red; }
Компилируется в:
.button[data-v-1234] { color: red; }
- Плюсы: полная изоляция стилей, отсутствие коллизий. Такие стили легко переносить между проектами и вы не рискуете случайно задеть существующие.
- Минусы: небольшой runtime/compile overhead, раздувание CSS из-за добавленных хешей.
Scoped удобен для быстрых прототипов, но для крупных проектов это чаще лишняя нагрузка.
module в Vue
Vue поддерживает ещё один способ изоляции — CSS Modules, через .
Click
.button { color: red; }
Классы получают уникальные имена при компиляции (например button_abc123) и доступ через объект $style.
- Плюсы: полная изоляция, удобно для динамических классов, можно комбинировать с BEM.
- Минусы: синтаксис чуть сложнее ($style вместо обычного класса), больше boilerplate, не так нагляден для людей привыкших к plain CSS.
Если BEM уже соблюдается, CSS Modules чаще всего не нужны, но для компонентов с динамическими классами могут быть полезны.
Уникальные имена классов (BEM)
Если проект использует строгий нейминг, например BEM (Block-Element-Modifier), scoped можно не применять. Классы блоков уже уникальные, а дочерние элементы и модификаторы ограничены областью блока:
.block {
display: flex;
flex-direction: column;
&__element {
flex-basis: 50%;
}
&--modifier {
flex-direction: row;
}
}
- Плюсы: plain CSS без data-v-xxxx, уменьшенный размер бандла, отсутствие runtime/compile overhead. Отсутствие коллизий при строгом следовании BEM.
- Минусы: требуется соблюдать BEM нейминг, который не всем по вкусу, незначительное увеличение времени на code review.
Этот вариант подходит для команд с code review и зафиксированными стандартами разработки.
Валидация классов и стилей
Соблюдение этих правил можно автоматизировать с помощью линтеров.
- Stylelint — запрет не-BEM классов:
{
"selector-class-pattern": "[a-z]([a-z-]+)?(__([a-z]+-?)+)?(--([a-z]+-?)+){0,2}"
}
- Eslint — запрет scoped в Vue-компонентов:
{
"vue/enforce-style-attribute": ["error", { "allow": ["plain"] }]
}
Заключение
- Scoped стилей можно смело избегать, если применяется строгий BEM.
- CSS без scoped уменьшает размер бандла и нагрузку на runtime.
- Линтеры stylelint и eslint помогут ускорить миграцию и предотвратить ошибки в будущем.
- Scoped остаётся безопасным и допустимым подходом, но только если понимать цену его использования.
#build #css #vue
При работе с Vue многие привычно используют , ограничивая стили текущим компонентом. Разберёмся, действительно ли это нужно, или стало устаревшей привычкой, от которой можно отказаться.
scoped в Vue
добавляет каждому селектору уникальный атрибут вроде data-v-xxxx.
Click
.button { color: red; }
Компилируется в:
.button[data-v-1234] { color: red; }
- Плюсы: полная изоляция стилей, отсутствие коллизий. Такие стили легко переносить между проектами и вы не рискуете случайно задеть существующие.
- Минусы: небольшой runtime/compile overhead, раздувание CSS из-за добавленных хешей.
Scoped удобен для быстрых прототипов, но для крупных проектов это чаще лишняя нагрузка.
module в Vue
Vue поддерживает ещё один способ изоляции — CSS Modules, через .
Click
.button { color: red; }
Классы получают уникальные имена при компиляции (например button_abc123) и доступ через объект $style.
- Плюсы: полная изоляция, удобно для динамических классов, можно комбинировать с BEM.
- Минусы: синтаксис чуть сложнее ($style вместо обычного класса), больше boilerplate, не так нагляден для людей привыкших к plain CSS.
Если BEM уже соблюдается, CSS Modules чаще всего не нужны, но для компонентов с динамическими классами могут быть полезны.
Уникальные имена классов (BEM)
Если проект использует строгий нейминг, например BEM (Block-Element-Modifier), scoped можно не применять. Классы блоков уже уникальные, а дочерние элементы и модификаторы ограничены областью блока:
.block {
display: flex;
flex-direction: column;
&__element {
flex-basis: 50%;
}
&--modifier {
flex-direction: row;
}
}
- Плюсы: plain CSS без data-v-xxxx, уменьшенный размер бандла, отсутствие runtime/compile overhead. Отсутствие коллизий при строгом следовании BEM.
- Минусы: требуется соблюдать BEM нейминг, который не всем по вкусу, незначительное увеличение времени на code review.
Этот вариант подходит для команд с code review и зафиксированными стандартами разработки.
Валидация классов и стилей
Соблюдение этих правил можно автоматизировать с помощью линтеров.
- Stylelint — запрет не-BEM классов:
{
"selector-class-pattern": "[a-z]([a-z-]+)?(__([a-z]+-?)+)?(--([a-z]+-?)+){0,2}"
}
- Eslint — запрет scoped в Vue-компонентов:
{
"vue/enforce-style-attribute": ["error", { "allow": ["plain"] }]
}
Заключение
- Scoped стилей можно смело избегать, если применяется строгий BEM.
- CSS без scoped уменьшает размер бандла и нагрузку на runtime.
- Линтеры stylelint и eslint помогут ускорить миграцию и предотвратить ошибки в будущем.
- Scoped остаётся безопасным и допустимым подходом, но только если понимать цену его использования.
#build #css #vue