Atrybuty class i style w Vue.js

Ten wpis jest 6 częścią z 7 w kursie Vue.js

Czym dla mnie jest Vue.js? To przede wszystkim genialne „developer experience”, czyli taki UX, ale w odniesieniu do wygody korzystania z narzędzia przydatnego w pracy programisty. Świetnym tego przykładem jest fakt, że Vue traktuje inaczej dwa atrybuty html – classstyle – sprawiając, że korzystanie z tego frameworka jest przyjemniejsze. Tego, co dokładnie się tam dzieje dowiesz się z tego tekstu.

Dynamicznie bindując atrybuty class oraz style możesz oczywiście używać stringów. Jednak często będziesz chcieć np. zaaplikować jakąś klasę, czy styl tylko pod pewnym warunkiem. Wtedy okaże się, że ręczne łączenie stringów jest bardzo niewygodne oraz, co ważniejsze, podatne na błędy. Dlatego w przypadku styli i klas, możesz do v-bind przekazać również obiekt.

Dynamiczne classy

Przekazując obiekt podczas bindowania klasy, możesz ją dynamicznie dodawać lub usuwać w zależności od tego, czy wartość dostępna pod kluczem ją reprezentującym jest prawdziwa:

.enabled {
  color: green;
}
new Vue({
  data() {
    return {
      isEnabled: true
    };
  }
}).$mount("#app");
<div id="app">
  <label :class="{ enabled: isEnabled }">
    <input type="checkbox" v-model="isEnabled" />
    Kliknij mnie!
  </label>
</div>

See the Pen mLWPZb by Wojciech Urbański (@wojtiku) on CodePen.

Oczywiście umieszczając w obiekcie więcej pól, możesz w ten sposób zarządzać dodawaniem/usuwaniem większej liczby klas.

Dodając dynamicznie klasy do elementów, bardzo często będziesz w sytuacji, gdy element ma np. 2-3 klasy przypisane do niego na stale oraz jedną klasę dynamiczną. Oczywiście pisanie wtedy obiektów w stylu { klasa1: true, klasa2: true, klasa3: dynamicznyBoolean } byłoby uciążliwe i monotonne. Właśnie dlatego możesz jednocześnie użyć na elemencie zwykłej, „statycznej” klasy oraz zbindować ją dynamicznie, a Vue inteligentnie połączy je ze sobą.

<div
  class="klasa-statyczna inna-klasa"
  :class="{ 'klasa-zalezna-od-warunku': isEnabled }"
>
  to takie proste!
</div>

Oprócz obiektów, możesz użyć też tablicy. Jej elementy mogą być albo stringami, albo obiektami. W pierwszym przypadku zostaną po prostu dopisane do atrybutu klasy jako rozdzielone spacją. Co ważne, elementy takiej tablicy mogą pochodzić z pól data. Obiekty obecne w tablicy dodadzą klasy odpowiadające swoim kluczom, o ile ich wartości będą prawdziwe – dokładnie tak, jak opisałem to wyżej.

new Vue({
  data() {
    return {
      someClass: 'some-weird-class',
      dynamicClasses: {
        first: true,
        second: false
      },
      isEnabled: true,
      isHighlighted: false
    };
  }
}).$mount("#app");
<div id="app">
  <p class="static-class" :class=[isEnabled ? 'enabled' : null, someClass, dynamicClasses, {highlighted: isHighlighted}]>
    Element, który ma je wszystkie!
  </p>
</div>

Powyższy element będzie miał klasy: enabled, some-weird-class, first oraz second. Takie konfiguracje dają ogromne możliwości. W praktyce, korzystam jednak głównie ze składni z obiektem napisanym wprost w szablonie (czyli tej, którą zademonstrowałem jako pierwszą).

Dynamiczne style

Atrybut style również jest specjalnie traktowany przez Vue. Tutaj także dostajesz do dyspozycji składnię obiektową, która działa trochę inaczej niż w przypadku class, ale za to bardzo jest podobna do zwykłego CSS. Klucze pól obiektu odpowiadają właściwościom CSS, a ich wartości… wartościom :).

Co ważne, klucze w takim obiekcie możesz pisać zarówno używając kebab-case, jak i camelCase – czyli po CSSowemu i JSowemu. Wybór należy do Ciebie.

new Vue({
  data() {
    return {
      selectedColor: null,
      underline: false
    };
  }
}).$mount("#app");
<div id="app">
  <label :style="{'background-color': selectedColor}">
    Wybierz kolor:
    <select v-model="selectedColor">
      <option disabled>Wybierz kolor</option>
      <option>lightyellow</option>
      <option>lightgreen</option>
      <option>lightblue</option>
      <option>lightpink</option>
    </select>
  </label>
  <label :style="{textDecoration: underline ? 'underline' : 'none' }">
    <input type="checkbox" v-model="underline" /> Underline?
  </label>
</div>

See the Pen v-bind:style by Wojciech Urbański (@wojtiku) on CodePen.

Tutaj również możesz użyć notacji tablicowej, aby złączyć ze sobą kilka obiektów.

Chociaż czasami spotkasz się z sytuacją, gdzie użycie styli inline jest konieczne, to pamiętaj, że generalnie nie powinno się ich używać – wpływają źle na modularność i reużywalność Twojego kodu HTML i CSS. Tam gdzie to możliwe, lepiej przypisać dane style do klasy i to ją dodawać lub usuwać z elementu.

Ćwiczenie

Wiesz już jak dynamicznie dodawać do elementu klasy i style inline. Użyj tej wiedzy do zrobienia prostego color pickera. Stwórz element input typu color, którego zmiana będzie zmieniała kolor tła elementu. Zadanie bonusowe: użyj do tego celu 3 inputów typu range odpowiadającym składowym R, G i B. Podziel się rozwiązaniem w komentarzu!