[Перевод] Vue.js для начинающих, урок 5: обработка событий
Сегодня, в пятом уроке курса по Vue.js для начинающих, речь пойдёт о том, как обрабатывать события.
→ Vue.js для начинающих, урок 1: экземпляр Vue
→ Vue.js для начинающих, урок 2: привязка атрибутов
→ Vue.js для начинающих, урок 3: условный рендеринг
→ Vue.js для начинающих, урок 4: рендеринг списков
Цель урока
Первая цель урока заключается в том, чтобы в карточке товара появилась бы кнопка, нажатия на которую увеличивают количество товара в корзине.
Вторая цель заключается в том, чтобы при наведении мыши на названия цветов вариантов товара менялось бы изображение товара.
Начальный вариант кода
В файле проекта index.html
будет присутствовать следующий код:
{{ product }}
In stock
Out of Stock
- {{ detail }}
{{ variant.variantColor }}
Вот содержимое main.js
:
var app = new Vue({
el: '#app',
data: {
product: "Socks",
image: "./assets/vmSocks-green.jpg",
inStock: true,
details: ['80% cotton', '20% polyester', 'Gender-neutral'],
variants: [
{
variantId: 2234,
variantColor: "green"
},
{
variantId: 2235,
variantColor: "blue"
}
]
}
})
Задача
Нам нужна кнопка, которой будет назначен прослушиватель события, реагирующий на щелчок по ней. По щелчку должен запускаться метод, который и выполняет увеличение количества товара в корзине.
Решение
Для начала — добавим, в main.js
, в объект data
, новое свойство, которое будет символизировать количество товара в корзине:
cart: 0
Cart({{ cart }}) Если теперь нажать на кнопку — количество товара в корзине увеличится на 1. Как всё это работает? Давайте разберёмся в представленной здесь конструкции. Использование директивы Это — простой, но не вполне реалистичный пример. Вместо того, чтобы указывать в кавычках выражение Тут используется механизм, очень похожий на тот, который мы уже применяем для хранения данных. А именно, речь идёт о том, что у объекта с опциями, используемого при создании экземпляра Vue, может быть необязательное свойство, носящее имя Продолжим разбор того, что здесь происходит. Кнопка прослушивает события Если бы мы просто написали бы в теле функции что-то вроде Возможно, вы сейчас задаётесь вопросом о том, что сейчас мы просто увеличиваем количество товаров в корзине, но самого товара в корзину не добавляем. Может, мы что-то делаем не так? Это — правильный вопрос. Мы реализуем соответствующий функционал позже, в одном из следующих уроков. Итак, теперь, когда мы изучили основы обработки событий во Vue, взглянем на более сложный пример. Для начала — давайте расширим объекты массива Вот соответствующий код в
{{ variant.variantColor }}
Создадим этот метод в Но тут мы обновляем значение, хранящееся в
Когда вызывается этот метод, → Вот заготовка, которую вы можете использовать для решения этой задачи. → Вот решение задачи. → Vue.js для начинающих, урок 1: экземпляр Vue
Теперь, в index.html
, добавим элемент , с помощью которого на страницу будет выводиться число, хранящееся в свойстве
cart
:
Ещё мы создадим в коде index.html
кнопку, которая позволяет добавлять товар в корзину:
Здесь обратите внимание на то, что для инкрементирования значения, хранящегося в cart
, мы используем директиву v-on
.
Страница с корзиной и с кнопкой для добавления товара в корзину v-on
сообщает Vue о том, что мы хотим прослушивать события, происходящие с кнопкой. Потом идёт двоеточие, после которого указывается то, какое конкретно событие нас интересует. В данном случае это — событие click
. В кавычках записано выражение, которое добавляет 1 к значению, хранящемуся в cart
. Это происходит при каждом щелчке по кнопке.cart += 1
, давайте сделаем так, чтобы щелчок по кнопке вызывал бы метод, который будет увеличивать значение, хранящееся в cart
. Вот как это выглядит:
Как видите, здесь addToCart
— это имя метода, который будет вызван при возникновении события click
. Но сам метод мы пока не объявили, поэтому давайте сделаем это прямо сейчас, оснастив им наш экземпляр Vue.methods
, в котором содержится объект с методами. В нашем случае это будет всего один метод — addToCart
: methods: {
addToCart() {
this.cart += 1
}
}
Теперь, когда мы щёлкаем по кнопке, вызывается метод addToCart
, который и увеличивает значение cart
, выводящееся в теге .
click
благодаря директиве v-on
, которая вызывает метод addToCart
. Этот метод находится в свойстве methods
экземпляра Vue. В теле функции содержится инструкция, добавляющая 1 к значению this.cart
. Так как this
хранит ссылку на то место, где хранятся данные экземпляра Vue, в котором мы находимся, функция добавляет 1 к значению cart
. А this.cart
— это то же самое, что и свойство cart
, объявленное в свойстве data
объекта с опциями.cart += 1
, то мы столкнулись бы с сообщением об ошибке cart is not defined
. Именно поэтому мы используем конструкцию this.cart
и обращаемся к cart
из экземпляра Vue, используя this
.variants
из объекта data
, добавив туда свойство variantImage
, хранящее путь к изображению нужного варианта товара. Приведём соответствующий раздел файла main.js
к такому виду: variants: [
{
variantId: 2234,
variantColor: "green",
variantImage: "./assets/vmSocks-green.jpg"
},
{
variantId: 2235,
variantColor: "blue",
variantImage: "./assets/vmSocks-blue.jpg"
}
],
Теперь каждому варианту товара, зелёным и синим носкам, назначено собственное изображение.Задача
Нужно, чтобы, по наведению мыши на название цвета варианта носков, в поле, где выводится изображение товара, вывелось бы изображение variantImage
для соответствующего цвета.Решение
Тут нам снова пригодится директива v-on
. Но в этот раз мы воспользуемся сокращённым вариантом её записи, который выглядит как @
. А прослушивать будем событие mouseover
.index.html
:
Обратите внимание на то, что мы передаём методу updateProduct
, в виде аргумента, variant.variantImage
.main.js
: updateProduct(variantImage) {
this.image = variantImage
}
Этот метод очень похож на тот, который мы недавно создавали для увеличения значения cart
.image
. А именно, в image
записывается то, что хранится в variantImage
того варианта товара, на который наведён указатель мыши. Соответствующее значение передаётся функции updateProduct
из самого обработчика события, находящегося в index.html
:
Другими словами, теперь метод updateProduct
готов к вызову с параметром variantImage
.variant.variantImage
передаётся ему в виде variantImage
и используется для обновления значения, хранящегося в this.image
. Мы, по аналогии с ранее рассмотренной конструкцией this.cart
, можем сказать, что this.image
— это то же самое, что image
. В результате значение, хранящееся в image
, теперь динамически обновляется в соответствии с данными варианта товара, на который наведён указатель мыши.Синтаксис ES6
Здесь мы, создавая методы, пользовались такими конструкциями: updateProduct(variantImage) {
this.image = variantImage
}
Это сокращённый вариант описания методов, который появился в ES6. Более старый вариант записи подобных конструкций выглядит так: updateProduct: function(variantImage) {
this.image = variantImage
}
Практикум
Создайте кнопку и соответствующий метод, которые позволят уменьшать значение, хранящееся в cart
.Итоги
Подведём итоги сегодняшнего занятия: v-on
.v-on
выглядит как @
.v-on
можно указать тип прослушиваемого события: v-on
может вызывать методы.v-on
, может принимать аргументы.this
содержит ссылку на то место, где хранятся данные текущего экземпляра Vue. Его использование позволяет работать с данными экземпляра, а так же с методами, объявленными в экземпляре.
Получилось ли у вас домашнее задание к этому уроку?
→ Vue.js для начинающих, урок 2: привязка атрибутов
→ Vue.js для начинающих, урок 3: условный рендеринг
→ Vue.js для начинающих, урок 4: рендеринг списков