Unetway

Работа с классами и стилями

Очень часто необходимо динамически изменять CSS-классы и стили элементов в зависимости от состояния приложения. Так как это - атрибуты, можно использовать v-bind, однако это не удобно и может приводить к ошибкам.
В Vue специально для работы с классами и стилями есть дополнительные возможности директивы v-bind. Эти атрибуты при динамической связывании могут принимать строки, массивы, объекты.

Связывание CSS-классов

Использование объектов

Для динамического задания или удаления CSS классов можно передать в директиву v-bind:class объект:

<div v-bind:class="{ active: isActive }"></div>

Запись выше обозначает, что наличие класса active будет определяться если параметр isActive является true.

Также, v-bind:class можно использовать и совместно с обычным атрибутом class:

<div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>

При использовании этих данных:

data: {
  isActive: true,
  hasError: false
}

Получится:

<div class="static active"></div>

При изменении isActive или hasError, список классов элемента тоже обновится.
Используемый при связывании объект не обязательно должен быть указан прямо в шаблоне:

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

Результат будет такой же. Еще можно использовать и вычисляемые свойства, возвращающие объекты.

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

Использование массивов

В v-bind:class можно передать массив:

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

В результате получим:

<div class="active text-danger"></div>

Чтобы переключить классы, переданные в массиве, можно использовать тернарный оператор:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

В этом случае errorClass будет применён к элементу всегда, а activeClass — только когда isActive является true.
Но такая конструкция становится немного громоздкой, если есть несколько классов. Поэтому можно использовать смешанный синтаксис:

<div v-bind:class="[{ active: isActive }, errorClass]"></div>

Использование с компонентами

При применении атрибута class к пользовательскому компоненту, классы будут добавлены к его корневому элементу. Собственные классы элемента потеряны не будут.

Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

Если указать дополнительные классы:

<my-component class="baz boo"></my-component>

В результате рендеринга будет:

<p class="foo bar baz boo">Hi</p>

Такое делается и для связывания классов с данными:

<my-component v-bind:class="{ active: isActive }"></my-component>

Если isActive истинно, HTML будет:

<p class="foo bar active">Hi</p>

Связывание inline-стилей

Использование объектов

Объектная запись для v-bind:style проста и выглядит почти как CSS,  но на самом деле, это объект JavaScript. Для указания свойств CSS можно применять как camelCase, так и kebab-case:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
  activeColor: 'red',
  fontSize: 30
}

Передача объекта стилей по имени может сделать код чище:

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

Можно также использовать и вычисляемые свойства, возвращающие объекты стилей.

Использование массивов

Запись v-bind:style с массивом позволяет применить несколько объектов стилей к одному и тому же элементу:

<div v-bind:style="[baseStyles, overridingStyles]"></div>

Автоматические префиксы

При использовании в v-bind:style свойств CSS, которые требуют указания вендорных префиксов, Vue автоматически определит это и добавит префиксы к стилям.

Множественные значения

Можно предоставить массив из нескольких (префиксных) значений для свойства style:

<div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

Это отобразит последнее значение в массиве.