Перейти к содержанию

Привязка классов и стилей

Чаще всего привязка данных необходима для работы со списком классов и встроенными стилями элемента. Поскольку class и style являются атрибутами, мы можем использовать v-bind для динамического присвоения им строкового значения, как и в случае с другими атрибутами. Однако попытка сгенерировать эти значения с помощью конкатенации строк может вызвать раздражение и привести к ошибкам. По этой причине Vue предоставляет специальные улучшения, когда v-bind используется с class и style. Помимо строк, выражения могут анализировать объекты или массивы.

Привязка классов HTML

Привязка к объектам

Мы можем передать объект в :class (сокращение от v-bind:class), чтобы динамически переключать классы:

template
<div :class="{ active: isActive }"></div>

Приведённый выше синтаксис означает, что наличие класса active будет определяться истинностью свойства данных isActive.

Вы можете переключать несколько классов, имея больше полей в объекте. Кроме того, директива :class может сосуществовать с передаваемым атрибутом class. Итак, дано следующее состояние:

js
const isActive = ref(true)
const hasError = ref(false)
js
data() {
  return {
    isActive: true,
    hasError: false
  }
}

И следующий шаблон:

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

Это отобразит:

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

При изменении isActive или hasError список классов будет обновлен соответствующим образом. Например, если hasError станет true, список классов станет "static active text-danger".

Связанный объект не обязательно должен быть встроенным:

js
const classObject = reactive({
  active: true,
  'text-danger': false
})
js
data() {
  return {
    classObject: {
      active: true,
      'text-danger': false
    }
  }
}
template
<div :class="classObject"></div>

Это отобразит:

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

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

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>

Привязка к массивам

Мы можем привязать :class к массиву, чтобы применить список классов:

js
const activeClass = ref('active')
const errorClass = ref('text-danger')
js
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
template
<div :class="[activeClass, errorClass]"></div>

Это отобразит:

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

Если вы хотите также условно переключать класс в списке, вы можете сделать это с помощью тернарного выражения:

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

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

Однако это может быть слишком многословным, если у вас несколько условных классов. Поэтому синтаксис объекта можно использовать и внутри синтаксиса массива:

template
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>

С компонентами

Этот раздел предполагает знание Компонентов. Не стесняйтесь пропустить его и вернуться позже.

Когда вы используете атрибут class в компоненте с одним корневым элементом, эти классы будут добавлены к корневому элементу компонента и объединены с любым существующим классом, уже имеющимся в нем.

Например, если у нас есть компонент с именем MyComponent и следующим шаблоном:

template
<!-- шаблон дочернего компонента -->
<p class="foo bar">Привет!</p>

Затем добавьте несколько классов при его использовании:

template
<!-- при использовании компонента -->
<MyComponent class="baz boo" />

HTML будет выглядеть следующим образом:

template
<p class="foo bar baz boo">Привет!</p>

То же самое справедливо и для привязки классов:

template
<MyComponent :class="{ active: isActive }" />

Если переменная isActive истинна, отображаемый HTML будет:

template
<p class="foo bar active">Привет!</p>

Если ваш компонент имеет несколько корневых элементов, вам нужно будет определить, какой элемент получит этот класс. Вы можете сделать это, используя свойство компонента $attrs:

template
<!-- Шаблон MyComponent с использованием $attrs -->
<p :class="$attrs.class">Привет!</p>
<span>Это дочерний компонент</span>
template
<MyComponent class="baz" />

Это отобразит:

html
<p class="baz">Привет!</p>
<span>Это дочерний компонент</span>

Вы можете узнать больше о наследовании атрибутов компонентов в главе Обычные атрибуты.

Привязка встроенных стилей

Привязка к объектам

:style поддерживает привязку к значениям объекта JavaScript — это соответствует свойству style элемента HTML:

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>

Хотя рекомендуется использовать ключи CamelCase, :style также поддерживает ключи свойств CSS в стиле кебаб (соответствует тому, как они используются в реальном CSS), например:

template
<div :style="{ 'font-size': fontSize + 'px' }"></div>

Зачастую полезно напрямую привязать объект стиля, чтобы шаблон был чище:

js
const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})
js
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
template
<div :style="styleObject"></div>

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

Директивы :style также могут сосуществовать с обычными атрибутами стиля, так же как и :class.

Шаблон:

template
<h1 style="color: red" :style="'font-size: 1em'">привет</h1>

Это отобразит:

template
<h1 style="color: red; font-size: 1em;">привет</h1>

Привязка к массивам

Мы можем привязать :style к массиву из нескольких объектов стиля. Эти объекты будут объединены и применены к одному и тому же элементу:

template
<div :style="[baseStyles, overridingStyles]"></div>

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

Когда вы используете свойство CSS, для которого требуется префикс поставщика в :style, Vue автоматически добавит соответствующий префикс. Vue делает это, проверяя во время выполнения, какие свойства стиля поддерживаются в текущем браузере. Если браузер не поддерживает определённое свойство, будут проверены различные варианты префикса, чтобы попытаться найти тот, который поддерживается.

Несколько значений

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

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

Это отобразит только последнее значение в массиве, которое поддерживает браузер. В этом примере он отобразит display: flex для браузеров, поддерживающих версию flexbox без префикса.

Привязка классов и стилей