0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

公式ホームページのIntro to Vue 3クラス6 (Event Handling)

Last updated at Posted at 2022-02-07

6. Event Handling

クラス https://www.vuemastery.com/courses/intro-to-vue-3/event-handling-vue3

VS Codeから該当フォルダを選択して、開きます。その後に、配下のgit部分をクリックして、ブランチをL6-startへ入れ替えてください。

ブランチ切り替え方法 https://qiita.com/phjg81/items/e6695eb2334d9297a318

今日のポイントはデータオブジェクトをイベントにより、変更されることです。

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' },
            ]
        }
    }
})

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 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">{{ variant.color }}</div>
            <button class="button">Add to Cart</button>
          </div>
        </div>
      </div>
    </div>

イベントに対する動作を実装するには、下記のようにdataと同レベルにてmethodsを追加して、その配下に実装したい関数を追記します。

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: {
        // method
        methodName() {
            // method context
        }
    }
})

その後に追加した部分にv-onを使って欲しいイベントを追加して見ます。

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

v-on:clickは@clickに諸略可能です。

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

付けられるイベントは下記の内容を参照してください。

https://developer.mozilla.org/ja/docs/Web/Events

ボタンをクリックしたら、cartへ追加する仕組みを実装して見ましょう。

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

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

image.png
image.png

mouse overイベントも追加して見ます。

main.js
    data() {
        return {
            ...
            image: './assets/images/socks_blue.jpg',
            ...
            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
          }
    }

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

今回の課題はカートから商品を取り出すボタンを追加して見たください。

課題確認
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
            }
        },
        updateImage(variantImage) {
            this.image = variantImage
        }
    }
})

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 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" @click="addToCart">Add to Cart</button>
            <!-- solution -->
            <button class="button" @click="removeFromCart">Remove Item</button>
          </div>
        </div>
      </div>
    </div>

パラメータ渡し

上記のように、関数へパラメータを追加しなくても、eventは関数へ引き渡され、使えます。

index.html
            <button class="button" @click="addToCart">Add to Cart</button>
main.js
const app = Vue.createApp({
    data() {
        return {
            ...
        }
    },
    methods: {
        addToCart(event) {
            if (event) {
                alert(event.target.tagName)
            }
            this.cart += 1
        },
        ...
    }
})

変数とeventを一緒に渡したい場合は、以下のように書けます。

index.html
            <button class="button" @click="addToCart('addToCart!', $event)">Add to Cart</button>
            <button class="button" @click="(event) => addToCart('addToCart!', event)">Add to Cart</button>
main.js
const app = Vue.createApp({
    data() {
        return {
            ...
        }
    },
    methods: {
        addToCart(message, event) {
            if (event) {
                event.preventDefault()
            }
            alert(message)
            this.cart += 1
        },
        ...
    }
})

イベントの修正

index.html
<!-- クリックイベントの伝播が停止します -->
<a @click.stop="addToCart"></a>

<!-- 送信イベントはページをリロードしなくなります -->
<form @submit.prevent="onSubmit"></form>

<!-- 修飾子は連鎖できます -->
<a @click.stop.prevent="addToCart"></a>

<!-- 修飾子のみ -->
<form @submit.prevent></form>

<!-- event.targetが自分である場合のみハンドラーをトリガーします -->
<!-- i.e. 子エレメントからではトリガーしません -->
<div @click.self="addToCart">...</div>

<!-- イベントリスナーを追加するときにキャプチャモードを使用する -->
<!-- i.e. 子エレメントを対象とするイベントは、これによって処理される前にここで処理されます -->
<div @click.capture="addToCart">...</div>

<!-- クリックイベントは最大で1回実行されます -->
<a @click.once="addToCart"></a>

<!-- `event.preventDefault()`が含まれている場合 -->
<!-- `onScroll`が完了するのを待つ代わりに  -->
<!-- スクロールイベントのデフォルトの動作(スクロール)が発生します   -->
<div @scroll.passive="onScroll">...</div>

キーイベント

down => press => up順で発生されます。

index.html
<!-- `Enter`キーを押下した時のみ`addToCart`を呼び出します  -->
<input @keyup.enter="addToCart" />

<!-- `Enter`キーを押下時のみ`vm.submit()`を呼び出します  -->
<input @keydown.enter="addToCart" />

<input @keypress.enter="addToCart" />

イベントの結合

index.html
<!-- Alt + Enter -->
<input @keyup.alt.enter="addToCart" />

<!-- Ctrl + Click -->
<div @click.ctrl="addToCart">Ctrl + Click</div>

<!-- これは、システムキー(ctrl、alt、shiftなど)が押されていない場合にのみ起動します -->
<button @keyup.exact="addToCart">システムキー</button>

マウスイベント

index.html
<!-- マウス左が押下時にイベントが発生します -->
<button @click.left="addToCart">left</button>
<!-- マウス右が押下時にイベントが発生します -->
<button @click.right="addToCart">right</button>
<!-- マウス中央が押下時にイベントが発生します -->
<button @click.middle="addToCart">middle</button>

vueのイベントハンドリング https://vuejs.org/guide/essentials/event-handling.html#calling-methods-in-inline-handlers
vueのキーハンドリング https://vuejs.org/guide/essentials/event-handling.html#key-modifiers

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?