Binding tříd a stylů
Běžným požadavkem na data binding je manipulace se seznamem tříd elementu a inline styly. Protože class
i style
jsou obojí atributy, můžeme podobně jako u jiných atributů použít v-bind
k dynamickému přiřazení string hodnoty. Pokusy o generování těchto hodnot pomocí spojování textových řetězců však mohou být otravné a náchylné k chybám. Z tohoto důvodu Vue poskytuje speciální vylepšení, když se v-bind
používá s class
a style
. Kromě řetězců lze výrazy vyhodnocovat také jako objekty nebo pole.
Binding HTML tříd
Binding na objekty
Do :class
(zkrácený zápis v-bind:class
) můžeme pro dynamickou aplikaci tříd přiřadit objekt:
template
<div :class="{ active: isActive }"></div>
Výše uvedený zápis znamená, že přítomnost třídy active
bude vyhodnocena na základě pravdivosti datové vlastnosti isActive
.
Více tříd můžete přepínat tím, že budete mít v objektu více hodnot. Kromě toho může direktiva :class
koexistovat s prostým atributem class
. Tedy za následujícího stavu:
js
const isActive = ref(true)
const hasError = ref(false)
A s následující šablonou:
template
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
Se vykreslí:
template
<div class="static active"></div>
Když se isActive
nebo hasError
změní, seznam tříd bude automaticky upraven podle potřeby. Například když se hasError
stane true
, seznam tříd se změní na "static active text-danger"
.
Připojený objekt nemusí být inline:
js
const classObject = reactive({
active: true,
'text-danger': false
})
template
<div :class="classObject"></div>
Výše uvedené vykreslí:
template
<div class="active"></div>
Můžeme také provést binding na computed proměnnou, která vrací objekt. Toto je běžný a účinný vzorec:
js
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
active: isActive.value && !error.value,
'text-danger': error.value && error.value.type === 'fatal'
}))
template
<div :class="classObject"></div>
Binding na pole
Do :class
můžeme přiřadit pole a aplikovat seznam tříd, které obsahuje:
js
const activeClass = ref('active')
const errorClass = ref('text-danger')
template
<div :class="[activeClass, errorClass]"></div>
Což vykreslí:
template
<div class="active text-danger"></div>
Pokud byste chtěli třídu v seznamu také přepínat podmíněně, můžete to udělat pomocí ternárního výrazu:
template
<div :class="[isActive ? activeClass : '', errorClass]"></div>
S tímto zápisem bude vždy aplikována errorClass
, ale activeClass
bude přidána pouze, pokud je isActive
pravdivé.
To však může být trochu nepřehledné, pokud máte podmíněných tříd více. Proto je kromě toho možné použít uvnitř pole i objektovou syntaxi:
template
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>
S komponentami
Tato sekce předpokládá znalost základů komponent. Klidně ji teď přeskočte a vraťte se později.
Když použijete atribut class
na komponentu s jedním root elementem, budou tyto třídy přidány do root elementu v komponentě a sloučeny s jakoukoli existující třídou, která se na něm již nachází.
Například pokud máme komponentnu jménem MyComponent
s následující šablonou:
template
<!-- šablona komponenty potomka -->
<p class="foo bar">Ahoj!</p>
A poté při použití přidáme nějaké třídy:
template
<!-- při použití komponenty -->
<MyComponent class="baz boo" />
Vykreslené HTML bude:
template
<p class="foo bar baz boo">Ahoj!</p>
To samé platí pro binding tříd:
template
<MyComponent :class="{ active: isActive }" />
Pokud je isActive
pravdivé, vykreslené HTML bude:
template
<p class="foo bar active">Ahoj!</p>
Pokud má vaše komponenta root elementů víc, budete muset definovat, který prvek třídu obdrží. Můžete to udělat pomocí vlastnosti komponenty $attrs
:
template
<!-- Šablona MyComponent s použitím $attrs -->
<p :class="$attrs.class">Ahoj!</p>
<span>Toto je potomek</span>
template
<MyComponent class="baz" />
Výše uvedené vykreslí:
html
<p class="baz">Ahoj!</p>
<span>Toto je potomek</span>
O dědičnosti atributů v komponentách se můžete dozvědět více v sekci Fallthrough atributy.
Binding inline stylů
Binding na objekty
:style
podporuje binding na hodnoty JavaScript objektů - v souladu s atributem HTML elementu style
:
js
const activeColor = ref('red')
const fontSize = ref(30)
template
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Ačkoli se doporučuje camelCase, :style
podporuje i CSS klíče zapsané kebab-case (v souladu s tím, jak jsou používány ve skutečném CSS) - například:
template
<div :style="{ 'font-size': fontSize + 'px' }"></div>
Často je dobrý nápad provést binding přímo s objektem stylu, aby byla šablona čistší:
js
const styleObject = reactive({
color: 'red',
fontSize: '30px'
})
template
<div :style="styleObject"></div>
Binding objektovým stylem se opět často používá ve spojení s computed proměnnými, které vracejí objekty.
Binding na pole
Můžeme provést binding :style
na pole více stylových objektů. Tyto objekty budou sloučeny a použity na stejný element:
template
<div :style="[baseStyles, overridingStyles]"></div>
Auto-prefixing
Když použijete CSS vlastnost, která vyžaduje vendor prefix, v rácmci :style
, Vue příslušnou předponu automaticky přidá. Dělá to tak, že za běhu zkontroluje, které vlastnosti stylu jsou podporovány v aktuálním prohlížeči. Pokud prohlížeč určitou vlastnost nepodporuje, budou testovány různé varianty s předponou, abychom se pokusili najít tu, která podporována je.
Více hodnot
Vlastnosti stylu můžete poskytnout pole více hodnot s předponou, například:
template
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
Tím se vykreslí pouze poslední hodnota v poli, kterou prohlížeč podporuje. V tomto případě vykreslí display: flex
pro prohlížeče, které podporují vlastnost flexbox bez předpony.