Урок 6 :: Event Handling :: Обработка событий

Вот, что мы с Вами сделаем на этом уроке.
Vue Mastery
Пройдем по этой ссылке:
Event Handling ➳

... Все внимательно послушаем, посмотрим, прочитаем.

Затем сделаем конспект (мой см ниже).

Конспект

Обработка событий
В этом уроке мы рассмотрим концепцию обработки событий.

Чтобы начать этот урок, вы можете либо получить программой git коммандой checkout исходный код в ветке
L6-start репозитория, либо перейти в CodePen, чтобы взять файлы там.

Примечание переводчика

Чтобы перейти на ветку с файлами начала урока 6 выполните команду:

git checkout L6-start

В стартовом коде вы увидите, что теперь у нас есть кнопка "Добавить в корзину"(Add to Cart), а также div корзины, который включает выражение для вывода значения наших новых данных корзины.

📄 index.html
<div class="cart">Cart({{ cart }})</div>
...
<button class="button">Add to Cart</button>

📄 main.js
data() {
  return {
    cart: 0,
    ...
  }
}

Наша Цель
Мы хотим иметь возможность нажать на кнопку (button) и этим действием увеличить на единицу значение свойства cart.

Прослушивание событий
Чтобы знать, когда нажата кнопка, нам нужно отслеживать события в этом элементе, в частности события клика. Мы можем достичь этого, используя директиву v-on.

📄 index.html
<button class="button" v-on:click="logic to run">Add to Cart</button>

Здесь мы говорим v-on о том, какой тип события следует прослушивать: клик (click). Внутри кавычек мы помещаем логику (или имя метода), которую мы хотим запустить, когда произойдет это событие (event).

Если мы напишем v-on:click="cart += 1", мы будем увеличивать значение корзины (cart) на 1, когда произойдет событие клика (click).

Запуск метода
Поскольку логика cart += 1 очень проста, мы могли бы написать это выражение напрямую в элементе button (кнопка). Но часто бывает нужно задействовать более сложную логику. В таких ситуациях мы можем добавить имя метода, которое будет выполнятся при совершении события. Давайте сделаем это сейчас.

📄 index.html
<button class="button" v-on:click="addToCart">Add to Cart</button>

Теперь, когда кнопка кликнута, будет запущен метод AddToCart. Давайте добавим этот метод в объект параметров нашего приложения Vue, вот так:

📄 main.js
const app = Vue.createApp({
  data() {
    return {
      cart: 0,
      ...
    }
  },
  methods: {
    addToCart() {
      this.cart += 1
    }
  }
})

Обратите внимание, как мы добавили опцию methods (методы), и внутри нее мы добавили новый метод AddToCart, который содержит ту же логику, что и в строке. Разница здесь в том, что теперь мы говорим this.cart, чтобы ссылаться на эту корзину (cart) в данных этого экземпляра Vue.

В браузере теперь мы должны иметь возможность нажать кнопку (button) "Добавить в корзину" ("Add To Cart") и увидеть, как значение корзины увеличивается на 1.

Понимание v-on
Давайте глубже рассмотрим, как работает эта обработка событий.
les06_pic01.jpg
Добавляя v-on к элементу, мы даем ему возможность прослушивать события. В этом случае мы указали, что прослушиваем события клика (click). Когда происходит клик (click), запускается метод AddToCart, который, как мы только что видели, принимает значение cart (корзины) и увеличивает его на единицу.

Стенография (сокращенная версия написания) для v-on
Как вы можете себе представить, прослушивание событий на элементах является очень распространенным явлением. Точно так же, как у v-bind есть стенография (:), у v-on есть стенография: @.

Таким образом, наш код можно было бы упростить так:

📄 index.html
<button class="button" @click="addToCart">Add to Cart</button>

Другой Пример: События Наведения Курсора Мыши (Mouseover)
Теперь, когда мы понимаем основы обработки событий, давайте поставим прослушку к событиям другого рода в нашем приложении Vue.

В настоящее время мы показываем различные цвета, “зеленый” (“green” ) и “синий” (“blue”), чуть ниже сведений о продукте:
les06_pic02.jpg
Было бы красиво, если бы, наведя курсор мыши на “зеленый” и “синий”, мы запустили обновление изображения до зеленого и синего изображения соответственно. Давайте, добавим возможность прослушивания событий наведения курсора мыши (mouseover) (термин Vue для “hover”) на эти названия цветов.

Поскольку мы хотим обновить изображение, отображаемое при наведении курсора мыши на различные цвета, я добавил новое свойство к каждому объекту из массива variants.

📄 main.js
data() {
  return {
    ...
    variants: [
      { id: 2234, color: 'green', image: './assets/images/socks_green.jpg' },
      { id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg' },
    ]
  }
}

Теперь у каждого варианта (variant) есть путь к изображению для зеленого и синего носков соответственно. Мы готовы добавить прослушиватель для событий наведения курсора мыши (mouseover) на variant color div.

📄 index.html
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)">{{ variant.color }}</div>

Когда происходит событие наведения курсора мыши (mouseover), мы запускаем метод updateImage, передавая путь к изображению каждого варианта. Этот метод выглядит следующим образом:

📄 main.js
methods: {
  ...
  updateImage(variantImage) {
    this.image = variantImage
  }
}

Он ожидает получение variantImage> в качестве параметра, и когда он запускается, он устанавливает this.image (в данных этого экземпляра Vue) равным вариантному изображению, которое было передано.

Теперь в браузере, когда мы наводим курсор мыши на “зеленый”, мы должны видеть зеленое изображение. Когда мы наведем курсор на “синий”, мы должны увидеть синее изображение.

Задача кодирования
Мы подошли к концу этого урока, теперь будем решать новые задачи кодирования.

Вот, что надо сделать.

Создайте новую кнопку button, при клики на которую будет производится увеличения количества товара в корзине (cart) на 1.

Вы можете найти код решения, загрузив L6-end ветвь репозитория или просмотрев решение в Codepen.

Чтобы перейти на ветку с файлами окончания урока 6 выполните команду:

git checkout L6-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">
            <img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image">
          </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)">{{ variant.color }}</div>
            <button class="button" v-on:click="addToCart">Add to Cart</button>
            <!-- solution -->
            <button class="button" @click="removeFromCart">Remove Item</button>
            <!-- solution -->
          </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',
            image: './assets/images/socks_blue.jpg',
            inStock: true,
            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
        },
        // solution
        removeFromCart() {
            if (this.cart >= 1) {
                this.cart -= 1
            }
        },
        // solution
        updateImage(variantImage) {
            this.image = variantImage
        }
    }
})





Результат выполнения данного урока

Cart({{ cart }})

{{ product }}

In Stock

Out of Stock

  • {{ detail }}
{{ variant.color }}


Примечание переводчика

1. Я слегка меняю контент оригинальных файлов курса для тренировки, проверки русификации и т.д.

2. Код для HTML я размещаю в этом файле между тегами body.

3. Обратите внимание, чтобы в консоле браузера не было ошибок.

Теперь Нажмите здесь для перехода к следующему уроку ➳

... или ...


Ссылки по теме.