Урок 7 :: Class & Style Binding :: Привязка к классу и стилю
Вот, что мы с Вами сделаем на этом уроке.
Пройдем по этой ссылке:
Class & Style Binding ➳
... Все внимательно послушаем, посмотрим, прочитаем.
Затем сделаем конспект (мой см ниже).
Конспект
Привязка к классу и стилюВ этом уроке мы рассмотрим концепцию привязки к классу и стилю.
Чтобы начать этот урок, вы можете либо получить программой git коммандой checkout исходный код в ветке
L7-start
репозитория, либо перейти в CodePen, чтобы взять файлы там.
Примечание переводчика
Чтобы перейти на ветку с файлами начала урока 7 выполните команду:
git checkout L7-start
Наша Цель
Привязка классов и стилей к нашим элементам на основе данных нашего приложения (объект
data
).
Привязка Стиля
На последнем уроке мы добавили функционал. При наведении курсора на “зеленый” или “синий” происходит обновление отображаемого изображения: появляются зеленые или синие носки соответственно. Но разве пользовательский интерфейс не был бы лучше, если бы вместо того, чтобы зависать над словом “зеленый” (“green”) или “синий” (“blue”), мы зависали над фактическими цветами зеленого и синего? Давайте создадим маленькие зеленые и синие кружки, на которые мы сможем навести курсор. Мы можем достичь этого с помощью привязки стилей.
Во-первых, чтобы оформить наши дивы в виде кругов, нам нужно будет добавить новый класс
.color-circle
к div, а котором у нас варианты товаров (т.е. носки зеленые и синие).
📄 index.html
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)" class="color-circle" </div>
Этот класс уже живет в нашем css-файле. Как вы можете видеть, он просто преобразует наши дивы в маленький круг диаметром 50 пикселей:
📄 styles.css
.color-circle { width: 50px; height: 50px; margin-top: 8px; border: 2px solid #d8d8d8; border-radius: 50%; }
Теперь, когда мы закончили с этим, мы можем перейти к фактической привязке стиля. Так же, как это звучит, мы хотим привязать стили к дивам. Мы делаем это, используя
v-bind
(или ее сокращение: :
) для атрибута стиля style
и привязывая к нему объект стиля.
📄 index.html
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)" class="color-circle" :style="{ backgroundColor: variant.color }"> </div>
Здесь мы устанавливаем цвет дивов
backgroundColor
равным variant.color
. Поэтому вместо того, чтобы печатать строки “зеленый” и “синий”, мы используем для выбора цвета фона наших кругов.
Проверив это в браузере, мы теперь должны увидеть два цветных круга, заполненных зеленым и синим фоном.
Круто! Теперь давайте на более глубоком уровне поймем, как все это работает.
Понимание Привязки Стиля
В нашем варианте
div
мы добавили атрибут style
и привязали к нему объект style.
📄 index.html
<div ... :style="{ backgroundColor: variant.color }"> </div>
Этот объект стиля имеет свойство CSS
backgroundColor
, и мы устанавливаем его равным соответствующему вариантному цвету во время текущей итерации v-for
.
В первой итерации
variant.color
имеет значение "green"
("зеленый").
Vue берет эту информацию и преобразует ее в код:
style="{ backgroundColor: green }"
Затем отображает кружок с зеленым фоном зеленом фоне.
Vue повторяет этот процесс для второго варианта цвета, чтобы создать синий круг.
Верблюд против Шашлыка (Camel vs Kebab)
Есть некоторые важные вещи, которые следует учитывать при использовании привязки стилей, подобной этой.
📄 index.html
<div :style="{ backgroundColor: variant.color }></div>
Внутри этого выражения помните, что этот объект стиля полностью является JavaScript. Вот почему я использовал camelCase в названии свойства. Если бы я сказал
background-color
, это было бы истолковано как знак минус. Но мы здесь не занимаемся никакой математикой. Мы задаем имя свойства CSS.
Поэтому, поскольку мы находимся в этом объекте JavaScript, мы должны использовать camelCased, если только мы не хотим использовать стиль Kebab в кавычках, чтобы избежать математического неправильного толкования, например так:
📄 index.html
<div :style="{ 'background-color': variant.color }></div>
Оба варианта будут работать. Помните про кавычки для стиля Kebab.
Привязка стиля: Объекты
Иногда вам может потребоваться добавить несколько стилей к элементу, но добавление их всех в строку может привести к беспорядку. В этих ситуациях мы можем привязаться ко всему объекту стиля, который находится в наших данных.
Теперь, когда мы рассмотрели тему привязки стилей, давайте рассмотрим аналогичную тему: привязка классов.
Привязка к классу Вернувшись в наше приложение, вы заметите, что, когда значение
data.InStock
равно false, мы все равно можем нажать кнопку "Добавить в корзину" ("Add to Cart") и увеличить значение количества товара в корзине. Но если товара нет на складе, возможно, мы не хотим, чтобы пользователь мог добавить товар в корзину. Поэтому давайте изменим это поведение, отключая кнопку всякий раз, когда InStock
имеет значение false
. Делая кнопку отключенной, используем привязку к классу.
Чтобы сделать это, мы будем использовать сокращение для
v-bind
атрибута disabled
, чтобы добавлять этот атрибут всякий раз, когда нашего продукта нет на складе.
📄 index.html
<button class="button" :disabled="!inStock" @click="addToCart"> Add to Cart </button>
Теперь всякий раз, когда
InStock
имеет значение false
и мы нажимаем кнопку "Добавить в корзину" ("Add to Cart"), ничего не произходит, так как он кнопка отключена. Но кнопка все еще кажется активной, что вводит в заблуждение наших пользователей. Поэтому давайте использовать привязку класса для добавления класса disabledButton
, а также всякий раз, когда InStock
имеет значение false
.
Вы увидите в нашем CSS-файле, что у нас уже есть этот класс
disabledButton
, который устанавливает цвет фона (background-color
) серым и делает курсор (cursor
) недопустимым.
📄 styles.css
.disabledButton { background-color: #d8d8d8; cursor: not-allowed; }
Чтобы применить этот класс по условию, на основе значения
InStock
, мы будем использовать сокращение для v-bind
атрибута класса и использовать выражение, которое добавляет класс disabledButton
(или нет) всякий раз, когда !InStock
.
📄 index.html
<button class="button" :class="{ disabledButton: !inStock }" :disabled="!inStock" @click="addToCart"> Add to Cart </button>
Теперь всякий раз, когда
InStock
имеет значение false
, кнопка не только будет отключена, но и будет отображаться отключенной.
Несколько Имен Классов
Приступая к работе с привязкой классов, следует отметить некоторые моменты. Например, что происходит, когда у нас уже есть существующий класс, и мы хотим условно добавить другой класс на основе значения данных?
Например, если у нас уже есть класс
color-circle
в этом div
, и мы условно добавим класс active
, как это будет выглядеть?
Эти классы будут объединены следующим образом:
📄 index.html
<div class="color circle active"></div>
Троичные (тернарные) операторы
Полезным инструментом, который дает нам привязка классов, является возможность использовать встроенные тернарные операторы для добавления различных классов на основе условия.
В этом случае, поскольку
isActive
является истинным, мы действительно добавляем класс activeClass
. Если бы это было ложно, мы бы не добавили класс (''
); в качестве альтернативы мы могли бы добавить совершенно другой класс.
Различия в синтаксисе и варианты использования, которые я только что показал вам с привязкой к классу и стилю, - это только начало. Поэтому я рекомендую ознакомиться с документами Vue для получения дополнительных вариантов использования и примеров.
Задача кодирования
Мы подошли к концу этого урока, теперь будем решать новые задачи кодирования.
Вот, что надо сделать.
Свяжите класс
out-of-stock-img
с картинкой, когда свойство inStock
равно false
.
Вы можете найти код решения, загрузив L7-end ветвь репозитория или просмотрев решение в Codepen.
Чтобы перейти на ветку с файлами окончания урока 7 выполните команду:
git checkout L7-end
Код файла index.html данного урока
<div id="app"> <div class="nav-bar"></div> <div class="cart">Cart({{ cart }})</div> <div class="product-display"> <div class="product-container"> <div class="product-image"> <!-- solution --> <img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image"> <!-- solution --> </div> <div class="product-info"> <h1>{{ product }}</h1> <p v-if="inStock">In Stock</p> <p v-else>Out of Stock</p> <ul> <li v-for="detail in details">{{ detail }}</li> </ul> <div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)" class="color-circle" :style="{ backgroundColor: variant.color }"> </div> <button class="button" :class="{ disabledButton: !inStock }" :disabled="!inStock" @click="addToCart"> Add to Cart </button> </div> </div> </div> </div> <!-- Import App --> <script src="./main.js"></script> <!-- Mount App --> <script> const mountedApp = app.mount('#app') </script>
Код файла main.js данного урока
const app = Vue.createApp({ data() { return { cart:0, product: 'Socks', brand: 'Vue Mastery', image: '../assets/images/socks_blue.jpg', inStock: false, details: ['50% cotton', '30% wool', '20% polyester'], variants: [ { id: 2234, color: 'green', image: '../assets/images/socks_green.jpg' }, { id: 2235, color: 'blue', image: '../assets/images/socks_blue.jpg' }, ] } }, methods: { addToCart() { this.cart += 1 }, updateImage(variantImage) { this.image = variantImage } } })
Результат выполнения данного урока
Cart({{ cart }})
{{ product }}
In Stock
Out of Stock
- {{ detail }}
Примечание переводчика
1. Я слегка меняю контент оригинальных файлов курса для тренировки, проверки русификации и т.д.
2. Код для
HTML
я размещаю в этом файле между тегами body
.
3. Обратите внимание, чтобы в консоле браузера не было ошибок.
Теперь Нажмите здесь для перехода к следующему уроку ➳
... или ...