Skip to content
Obsah stránky

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)
js
data() {
  return {
    isActive: true,
    hasError: 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
})
js
data() {
  return {
    classObject: {
      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'
}))
js
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.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')
js
data() {
  return {
    activeClass: 'active',
    errorClass: '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="[{ active: 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)
js
data() {
  return {
    activeColor: 'red',
    fontSize: 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: '13px'
})
js
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
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.

Binding tříd a stylů has loaded