BEM v Vue: struktura stylů pro škálovatelné komponenty
BEM zůstává aktuální ve projektech s Vue díky přísné hierarchii tříd, která zabraňuje konfliktům stylů v komponentové architektuře. Vue se soustředí na reaktivitu a logiku, zatímco BEM zajišťuje nezávislost bloků a elementů. Tato kombinace minimalizuje zmatek v CSS při růstu aplikace.
BEM je postaven na třech principech:
- Blok: nezávislá entita jako
.headernebo.card, bez vnějších závislostí. - Element: část bloku, označená dvojitým podtržením —
.button__icon. - Modifikátor: varianta nebo stav přes jednoduché podtržení —
.button_disabled,.card_theme_dark.
Taková struktura umožňuje izolovat styly, což usnadňuje ladění a refaktorování.
Stylování v Vue komponentách
Ve Vue se styly píšou uvnitř <style scoped>, což omezuje jejich rozsah na komponentu. Scoped zabraňuje únikům stylů, ale vyžaduje opatrnost s vnořováním.
:deep() se používá pouze pro integraci s externími knihovnami, kde scoped nestačí. Vyhněte se mu pro obcházení vlastní architektury — to je známka problémů ve struktuře.
BEM doplňuje scoped, logicky seskupuje třídy. Blok definuje základní styl, modifikátory — variace, elementy — vnitřní strukturu.
Praktický příklad: tlačítko se stavy
Bez systému se třídy chaoticky množí. Podívejte se na typickou chybu:
template>
<button :class="{
'button-basic': isBasic,
'button-href': isHref,
'button-avatar': isAvatar
}">
{{ text }}
</button>
</template>
Problémy:
- Absence hierarchie: třídy nejsou spojeny s blokem.
- Škálování: nové stavy vyžadují dodatečné podmínky.
- Čitelnost: s časem se logika ztrácí.
S BEM se šablona zjednodušuje a dokumentuje:
template>
<button :class="[
'button',
{
'button_disabled': disabled,
'button_loading': loading,
},
{
'button_size_xl': size === 'xl',
'button_size_l': size === 'l',
},
{
'button_primary': color === 'primary',
'button_secondary': color === 'secondary',
}
]">
{{ text }}
</button>
</template>
Třídy jsou rozděleny podle sémantiky: základní blok, stavy, velikosti, témy. V CSS:
.button {
/* základní styly */
padding: 12px 24px;
border: none;
border-radius: 4px;
}
.button_disabled {
opacity: 0.5;
cursor: not-allowed;
}
.button_loading {
position: relative;
}
.button_primary:not(.button_disabled):hover {
background-color: #0055ff;
}
Selektor :not() filtruje konfliktující stavy bez zbytečných tříd.
Škálování a týmová práce
Ve velkých projektech BEM snižuje kognitivní zátěž: vývojář vidí blok a jeho modifikátory přímo v šabloně. Není třeba prohledávat CSS, abyste pochopili styly.
Výhody v týmu:
- Předvídatelnost: názvy tříd odrážejí účel.
- Izolace: bloky na sebe nemají vliv.
- Rozšiřitelnost: nové modifikátory se přidávají bez refaktorování.
Příklad složitého komponentu — karta produktu s tématy a velikostmi:
template>
<div class="card" :class="[
`card_size_${size}`,
`card_theme_${theme}`
]
">
<div class="card__image"></div>
<div class="card__title">{{ title }}</div>
<button class="card__button button">Koupit</button>
</div>
</template>
Elementy uvnitř bloku dědí kontext, ale zůstávají nezávislé.
Kdy se vzdát BEM
BEM je nadbytečný pro prototypy nebo landing pages: Tailwind nebo utility třídy jsou rychlejší. Používejte BEM v projektech s dlouhodobou podporou, týmem a složitým UI.
Co je důležité
- BEM doplňuje Vue, zajišťuje přísnou hierarchii bez konfliktů se scoped.
- Modifikátory seskupují stavy a varianty, zjednodušují šablony.
:deep()— pouze pro externí knihovny, ne pro vnitřní strukturu.- Ve velkých projektech BEM zrychluje onboarding a refaktorování.
- Testujte na reálném komponentu: čitelnost se okamžitě zvýší.
— Editorial Team
Zatím žádné komentáře.