Vueのイベントでユーザーインタラクションを作成する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Open Sourcing MentalIllnessを選択して寄付を受け取りました。

序章

Vue.js 開発では、クライアントのWebブラウザーがHTMLと JavaScript を読み取り、開発者が記述した指示に基づいてWebページをレンダリングします。 しかし、Webページまたはアプリケーションはデータを処理する必要があるだけではありません。 また、ユーザーの操作を処理する必要があります。 これを行うために、開発者は、ユーザーがHTML要素を操作したときにコードを実行するJavaScriptイベントを使用します。

イベントは、ユーザーインターフェイスボタンまたは物理的なキーボードまたはマウスを使用したユーザーの操作をキャプチャできます。 JavaScriptでは、イベントリスナーを作成して、そのイベントが発生するのを待ってから、コードのブロックを実行します。 Vue.jsでは、イベントをリッスンする必要はありません。 これは、v-on:ディレクティブを使用して自動的に実行されます。

このチュートリアルでは、Vueのイベントを使用して、空港コードのアプリケーションを作成します。 ユーザーが空港コードを選択すると、アプリはその空港を「お気に入り」コレクションに追加します。 このプロジェクトをフォローすることで、イベントとは何か、Vueの組み込みイベントの使用方法、および独自のカスタムイベントを作成する方法を学習します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

ステップ1—プロジェクトの設定

このチュートリアルの最初のステップは、ビューに表示するデータを使用してデモプロジェクトを設定することです。 これには、空港データを含むJavaScriptオブジェクトarray と、データを反復してレンダリングするためのVueコンポーネントが含まれます。

まず、VueCLIを使用してプロジェクトを生成します。

vue create favorite-airports

これにより、favorite-airportsという名前のプロジェクトが作成されます。 このチュートリアルではVue3を使用するため、プロンプトが表示されたら、オプションDefault (Vue 3) ([Vue 3] babel, eslint)を選択します。

OutputVue CLI v4.5.6
? Please pick a preset:
  Default ([Vue 2] babel, eslint)
❯ Default (Vue 3) ([Vue 3] babel, eslint)
  Manually select features

プロジェクトを作成したら、このプロジェクトのすべてのローカルデータを保持するディレクトリを作成します。 まず、新しいプロジェクトフォルダを作業ディレクトリにします。

cd favorite-airports

次に、srcディレクトリにdataディレクトリを作成します。

mkdir src/data

選択したテキストエディタで、src/data/airports.jsというファイルを開きます。 次のデータをファイルに追加します。

お気に入り-airports/src / data / airports.js

export default [
  {
    name: 'Cincinnati/Northern Kentucky International Airport',
    abbreviation: 'CVG',
    city: 'Hebron',
    state: 'KY',
  },
  {
    name: 'Seattle-Tacoma International Airport',
    abbreviation: 'SEA',
    city: 'Seattle',
    state: 'WA',
  },
  {
    name: 'Minneapolis-Saint Paul International Airport',
    abbreviation: 'MSP',
    city: 'Bloomington',
    state: 'MN',
  },
  {
    name: 'Louis Armstrong New Orleans International Airport',
    abbreviation: 'MSY',
    city: 'New Orleans',
    state: 'LA',
  },
  {
    name: `Chicago O'hare International Airport`,
    abbreviation: 'ORD',
    city: 'Chicago',
    state: 'IL',
  },
  {
    name: `Miami International Airport`,
    abbreviation: 'MIA',
    city: 'Miami',
    state: 'FL',
  }
]

このデータは、米国内のいくつかの空港で構成されるオブジェクトの配列です。 次に、このデータを反復処理して、name abbreviationcity、およびstateプロパティで構成されるカードを生成します。 ユーザーがカードをクリックすると、アプリは親にイベントを送信します。これにより、お気に入りの空港を表すデータのコレクションにその空港が追加されます。

airport.jsファイルを保存して閉じます。

データをレンダリングするには、src/components/AirportCard.vueという名前の単一ファイルコンポーネント(SFC)を作成し、テキストエディターで開きます。 このコンポーネントには、エアポートカードのすべてのスタイルとロジックが含まれます。

次の内容をファイルに追加します。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>

<script>
export default {
  props: {
    airport: {
      type: Object,
      required: true
    }
  }
}
</script>

<style scoped>
.airport {
  border: 3px solid;
  border-radius: .5rem;
  padding: 1rem;
}

.airport p:first-child {
  font-weight: bold;
  font-size: 2.5rem;
  margin: 1rem 0;
}

.airport p:last-child {
  font-style: italic;
  font-size: .8rem;
}
</style>

このコンポーネントにはpropが含まれています。これは、Vue.jsで、親コンポーネントから子コンポーネントにデータを渡す方法です。 次に、templateセクションがこのデータをレンダリングします。 単一ファイルコンポーネントの詳細については、Vue単一ファイルコンポーネントを使用してコードの再利用可能なブロックを作成する方法チュートリアルを確認してください。

コードスニペットにCSSが含まれていることに気付くかもしれません。 AirportCard.vueコンポーネントでは、ラッパー<div>airportのクラスが含まれています。 このCSSは、各空港にカードの外観を与えるために境界線を追加することにより、生成されたHTMLにスタイルを追加します。 :first-child:last-childは、div内のHTMLの最初と最後のpタグに異なるスタイルを適用する疑似セレクターです。 ]airportのクラス。

ファイルを保存して、テキストエディタを終了します。

次に、既存のApp.vueコンポーネントを変更して、airports.jsデータを反復処理し、一連のAirportCards.vueコンポーネントをレンダリングします。 テキストエディタでsrc/App.vueを開き、内容を次の強調表示されたコードに置き換えます。

お気に入り-airports/src / App.vue

<template>
  <div class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
    </div>
  </div>
</template>

<script>
import { ref } from 'vue'
import allAirports from '@/data/airports.js'
import AirportCard from '@/components/AirportCard.vue'

export default {
  components: {
    AirportCard
  },
  setup() {
    const airports = ref(allAirports)
    return { airports }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 1rem;
  max-width: 960px;
  margin: 0 auto;
}
</style>

これにより、データとSFCがインポートされ、v-forディレクティブを使用してデータが反復処理され、airport.js配列内のオブジェクトごとにエアポートカードが作成されます。 また、[X42X]CSSグリッドを使用してカードのレイアウトを管理するwrapperクラスを対象としたCSSを追加します。

ファイルを保存して終了します。 プロジェクトがセットアップされたら、次のコマンドを使用してローカル開発サーバーを実行します。

npm run serve

これにより、localhost、通常はポート:8080でサーバーが起動します。 選択したWebブラウザーを開き、localhost:8080にアクセスして、以下を見つけます。

サンプルプロジェクトを設定したので、次にv-onディレクティブを使用して組み込みイベントを調べます。 このイベントが発生すると、アラートポップアップボックスが表示され、そのイベントに関連付けられている空港の空港コードが示されます。

ステップ2—v-onディレクティブを使用してイベントをリッスンする

前述のように、イベントは、ユーザーが DOM(ドキュメントオブジェクトモデル)のHTML要素を操作するときに関数を実行する方法です。 バニラJavaScriptを作成する場合、イベントで関数を実行するには、イベントリスナーと呼ばれるものを作成できます。 イベントリスナーは、その相互作用が発生するのを待ってから、コードを実行する関数です。 ただし、Vueでは、この目的でv-onディレクティブを使用できます。 ディレクティブは、開発者がDOMを操作するために使用できる再利用可能なコードの一部です。 v-onディレクティブは、そのままVue.jsによって提供されます。

このステップでは、ユーザーがカードをクリックしたときに実行される関数をアプリケーションに作成します。 選択したテキストエディタでsrc/components/AirportCard.vueコンポーネントを開きます。

次の強調表示されたコードを追加して、空港のユーザーにクリックしたことを警告する関数を作成します。

お気に入り-airports/src / components / AirportCard.vue

...
<script>
export default {
  props: {
    airport: {
      type: Object,
      required: true
    }
  },
  setup() {
    function selectAirport(airport) {
      alert(`You clicked on ${airport.abbreviation}. It's located in ${airport.city}, ${airport.state}.`)
    }

    return { selectAirport }
  }
}
</script>
...

Vue.js 3では、リアクティブ関数をsetupコンポーネントメソッドで定義およびエクスポートする必要があります。 これは、<template>selectAirport機能を実行できることをVueに通知します。

関数を定義したら、それをHTML要素のイベントにアタッチします。 前述のように、v-onディレクティブを使用して、clickという名前のイベントを添付できます。 これはVue.jsによって提供されるイベントです。 AirportCard.vueコンポーネントで、v-onディレクティブをラッパー<div>に追加します。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport" v-on:click="selectAirport(airport)">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>
...

このコードを追加したら、ファイルを保存して終了します。

これで、カードをクリックすると、提供されたメッセージとともにアラートがポップアップ表示されます。 たとえば、CVGをクリックすると、次のように表示されます。

clickイベントは、Vue.jsによってすぐに提供される唯一のイベントではありません。 実際、v-onは、次のような任意のネイティブJavaScriptイベントを使用できます。

  • keyup
  • mouseover
  • focus
  • mouseenter
  • change

次に、このv-on:clickリスナーをmouseoverに変更して、Vue.jsがイベントをリッスンする方法を示します。 mouseoverは、マウスカーソルがHTML要素上に移動するたびに発生するイベントです。

src/components/AirportCard.vueを再度開き、次の強調表示されたコードでファイルを更新します。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport" @mouseover="selectAirport(airport)">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>

ここに示すように、Vueにはv-on:イベントの省略構文もあります。 省略構文を使用するには、v-on@に置き換えました。 ファイルを保存して終了します。

これで、localhost:8080にアクセスしてカードにカーソルを合わせると、その関数が実行され、ネイティブアラートが表示されます。

この機能はテスト目的には適していますが、ユーザーがカーソルを合わせるたびにアラートが表示されるため、望ましくない場合があります。 より良いエクスペリエンスは、ユーザーがそのカードに初めてカーソルを合わせたときにのみ表示することです。 バニラJavaScriptでは、ユーザーがカードにカーソルを合わせた回数を追跡し、それ以上の実行を防ぐことができます。 Vue.jsにはイベント修飾子があり、これを利用してより少ないコードで同じことを実現できます。

次のセクションでは、イベント修飾子を調べて、ユーザーエクスペリエンスを向上させるためにそれらを使用します。

ステップ3—イベントおよびキー修飾子の使用

前のセクションでは、clickおよびmouseoverイベントで関数を実行しました。 また、v-onイベントのVue.jsの省略形についても学びました。 次に、このmouseoverイベントに修飾子を付加して、関数が1回だけ実行されるようにすることで、これをさらに拡張します。

Vue.jsは、いくつかのイベント修飾子を提供します。 これらのいくつかは次のとおりです。

  • .stop:イベントの伝播を停止します
  • .prevent:HTML要素のデフォルトの動作を防ぎます
  • .capture:選択した要素の前にある内部要素を対象とするイベントを処理します
  • .selfevent.targetが要素自体である場合にのみハンドラーをトリガーします
  • .once:関数を1回だけ実行します
  • .passive:イベントを待つのではなく、要素のデフォルトの動作をすぐに実行できるようにします。これは、モバイルデバイスでのスクロールのパフォーマンスを最適化するために使用できます。

この場合、.once修飾子を使用します。 テキストエディタで、AirportCard.vueコンポーネントを開き、既存のmouseoverイベントに修飾子を追加します。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport" @mouseover.once="selectAirport(airport)">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>

ファイルを保存します。 ブラウザでアプリケーションにアクセスすると、最初のmouseoverイベントでイベントが1回だけ発生することがわかります。

次に、キー修飾子を使用して修飾子の探索を続けます。 これらのキー修飾子は、keyupなどのキーストロークイベントに関連付けられています。 この次の部分では、このクリックアクションをもう少し明確にしたいことを想像してください。 これを行う1つの方法は、テンプレートの.airport<div>@clickイベントにキー修飾子を追加することです。

これを行うには、@mouseover@clickに変更し、.shift修飾子を追加します。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport" @click.shift="selectAirport(airport)">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>

変更を保存して、ブラウザでアプリケーションを開きます。 SHIFTキーを押さずにカードをクリックしても、アラートは何もしません。 次に、SHIFTキーを押しながらカードをクリックしてみてください。 これで関数が実行され、アラートが送信されます。

このセクションでは、Vueの組み込みイベントとそれらのイベントに関連する修飾子について学習しました。 これらの組み込みイベントで多くのことを成し遂げることができますが、カスタムイベントが必要になる場合があります。 次のセクションでは、カスタムイベントを使用して、親にアクションを発行し、関数を実行するようにします。

ステップ4—カスタムイベントの作成

Vue.jsでアプリケーションを開発する場合、カスタムイベントを介して親コンポーネントにデータを渡す必要がある場合があります。 小道具は親から子に渡される読み取り専用データですが、$emitを介したカスタムアクションはその逆です。 最も再利用可能なコンポーネントを作成するには、これらを関数と考えるのが最善です。 小道具(引数)を介してデータを渡し、値を親に戻します(return値)。

子コンポーネントから親にイベントを発行するには、$emit関数を使用します。 これを実装する前に、このチュートリアルでは、これがどのように機能するかを示す例を紹介します。

$emit関数は、アクション名(文字列)と親に渡す値の2つの引数を受け入れます。 次の例では、ユーザーがボタンをクリックすると、アクションfavoriteAirportの下で値CVGが親コンポーネントに送信されます。

ChildComponent.vue

<template>
  <button @click="$emit('favoriteAirport', 'CVG')">A button</button>
</template>

親コンポーネントでは、v-onディレクティブを使用して、favoriteAirportイベントをリッスンします。 このカスタムイベントが発生すると、コードは次の値で何かを実行します。

ParentComponent.vue

<template>
  <child-component @favoriteAirport="favoriteAirport = $event" />
</template>

<script>
import { ref } from 'vue'
export default {
  setup() {
    const favoriteAirport = ref('')

    return { favoriteAirport }
  }
}
</script>

イベントの値は$eventになります。 この場合、$eventは実際にはCVGであり、favoriteAirportと呼ばれるリアクティブデータプロパティに格納されます。

カスタムイベントがどのように見えるかがわかったので、このカスタムイベントをアプリケーションに実装することで、それを実践します。

テキストエディタでAirportCards.vueコンポーネントを開きます。 @clickイベントで、関数への参照を削除し、$emit("favoriteAirport", airport)に置き換えます。 最初のarugmentはイベントの名前であり、2番目はあなたが放出している値であることを忘れないでください。

お気に入り-airports/src / components / AirportCard.vue

<template>
  <div class="airport" @click="$emit('favoriteAirport', airport)">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>
...

ファイルを保存します。 これで、ユーザーが空港カードをクリックすると、カスタムイベントが発生し、そのairportオブジェクトが渡されます。

次に、src/App.vueを開いて、テンプレートにHTMLを追加します。 すでに存在する6枚のカードの後にお気に入りの空港リストを表示します。

お気に入り-airports/src / App.vue

<template>
  <div class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
    </div>
    <h1 v-if="favoriteAirports.length">Favorite Airports</h1>
    <div v-for="airport in favoriteAirports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
   </div>
  </div>
</template>

<script>
import { ref } from 'vue'
import allAirports from '@/data/airports.js'
import AirportCard from '@/components/AirportCard.vue'

export default {
  components: {
    AirportCard
  },
  setup() {
    const airports = ref(allAirports)
    const favoriteAirports = ref([])

    return { airports, favoriteAirports }
  }
}
</script>
...

このコードスニペットでは、空の配列であるfavoriteAirportsと呼ばれるリアクティブデータプロパティを作成しています。 <template>では、前の手順で行ったように、空の配列を反復処理して<airport-card />コンポーネントをレンダリングします。

次に、カスタムイベントにv-onイベントを追加する必要があります。

お気に入り-airports/src / App.vue

<template>
  <div class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation">
      <airport-card :airport="airport" @favoriteAirport="favoriteAirports.push($event)" />
    </div>
    <h1 v-if="favoriteAirports.length">Favorite Airports</h1>
    <div v-for="airport in favoriteAirports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
   </div>
  </div>
</template>
...

@favoriteAiportカスタムイベントでは、JavaScript push()メソッドを使用して、子($event)からfavoriteAirportsリアクティブデータに空港を追加しました財産。

ブラウザを開き、localhost:8080でプロジェクトに移動します。 空港カードの1つをクリックすると、そのカードがお気に入りの空港の下に表示されます。

このセクションでは、カスタムイベント、それらが何であるか、およびそれらの使用方法について学習しました。 カスタムイベントは、Vueが提供する$emit関数を介して親コンポーネントにデータを渡す方法です。 そのデータが出力されたら、配列に追加するなど、親コンポーネントでさらに操作できます。

結論

このチュートリアルでは、Vue.jsがclickmouseoverなどの多くの組み込みイベントをリッスンする方法を学びました。 それに加えて、イベントとキー修飾子、追加機能を提供するためにイベントに追加した小さなコードを試してみました。 これにより、.once修飾子を使用して関数を1回実行し、.shift修飾子を使用してSHIFTキーを押したときにのみ起動するようにアプリを設定します。

Vueは、イベントリスナーを手動で設定するよりも、データの操作に集中できるイベントをリッスンする効率的な方法を提供します。 それに加えて、Vueではコンポーネントを関数と考えることができます。コンポーネントはデータpropsを受け入れ、$emitで値を返すことができます。

Vueコンポーネントの詳細については、Vueドキュメントを読むことをお勧めします。 Vueのその他のチュートリアルについては、Vue.jsシリーズページを使用してWebサイトを開発する方法を確認してください。