PR
スポンサーリンク

Vue.jsで子コンポーネントのイベントを親コンポーネントで受け取る

今回は、Vue.jsを使用してボタンを非活性化するで作成したボタンを使用して子コンポーネントにも同じボタンを作成して子コンポーネントのイベントを親コンポーネントで受け取るプログラムを作成していきたいと思います。

イメージをお伝えするために先に完成形の画像をお見せします。

Helloボタンが押下された際にはHellogボタンのみメッセージが変更され、Vueボタンが押下された際にはVueボタンのみメッセージが変更されています。

画像だけではわかりませんがHelloボタンは親コンポーネントで作成しており、Vueボタンは子コンポーネントで作成しています。

VSCodeのディレクトリ構造は以下の画像の通りです。今回使用しているのはApp.vueとChildComponent.vueのみになります。

では実際にコードを見てみましょう。

C:/npm_sample/src/App.vue

<template>
  <div id="app">
    <button @click="changeMessage" class="messageButton" :disabled="isDisabled">{{ message }}</button>
    <!-- 子コンポーネントを追加し、イベントをリッスンする -->
    <ChildComponent @change-message="updateMessage" />
  </div>
</template>

<script>
import ChildComponent from './components/ChildComponent.vue' // 子コンポーネントをインポート

export default {
  name: 'App',
  components: {
    ChildComponent // 子コンポーネントを登録
  },
  data() {
    return {
      message: 'Hello',
      isDisabled: false,
    }
  },
  methods: {
    changeMessage() {
      if (this.message === 'Hello') {
        this.message = 'Updated message';
      } else {
        this.message = 'Hello';
      }
      // 親コンポーネントのボタンを非活性にする
      this.isDisabled = true;
    },
  }
}
</script>

<style>
/* 既存のスタイル */
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex; /* Flexboxを使用してレイアウトを調整 */
  justify-content: center; /* 横方向に中央寄せ */
  align-items: center; /* 縦方向にも中央寄せ */
  height: 100vh; /* 親要素の高さをビューポートの高さと同じにする */
}

.messageButton {
  background-color: #4CAF50;
  border: none;
  color: white;
  padding: 10px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  transition-duration: 0.4s;
  cursor: pointer;
  border-radius: 8px;
}

.messageButton:disabled {
  background-color: #e0e0e0;
  color: #a0a0a0;
  cursor: not-allowed;
}
</style>

コードの解説をします

構造

  • <template>セクション: この部分はHTMLマークアップを含み、ユーザーインターフェイスを定義します。id="app"を持つ<div>は、Vueインスタンスによって管理される最上位の要素です。
  • <script>セクション: JavaScriptのコード。Vueコンポーネントのロジックを定義します。コンポーネントのオプション(データ、メソッド、他のコンポーネントなど)を含みます。
  • <style>セクション: CSSスタイル。このコンポーネントに適用されるスタイルを定義します。

主要機能

  1. データプロパティ: messageisDisabledは、このコンポーネントの状態を表すデータプロパティです。messageはボタンに表示されるテキストを保持し、isDisabledはボタンの活性/非活性状態を管理します。
  2. メソッド: changeMessageは、ボタンがクリックされたときに実行される関数です。このメソッドはmessageの値を切り替え、ボタンを非活性にします(isDisabledtrueに設定)。
  3. イベントハンドリング: @click="changeMessage"は、ボタンがクリックされたときにchangeMessageメソッドを呼び出すための指示です。
  4. プロパティバインディング: :disabled="isDisabled"は、disabled属性をisDisabledデータプロパティの値にバインドします。これにより、isDisabledtrueの場合、ボタンは非活性になります。
  5. 子コンポーネントの使用: <ChildComponent @change-message="updateMessage" />は、ChildComponentをインポートして使用し、change-messageイベントが発生したときにupdateMessageメソッドを呼び出すように設定します。この機能により、子コンポーネントから親コンポーネントへの通信が可能になります。
  6. コンポーネントのインポートと登録: import ChildComponent from './components/ChildComponent.vue'ChildComponentをこのファイルにインポートします。components: { ChildComponent }は、親コンポーネント内でChildComponentを使用できるように登録します。

スタイル

  • #app.messageButton、および.messageButton:disabledセレクターを使って、このコンポーネントにスタイルを適用します。これらのスタイルはボタンの見た目を定義し、非活性状態のときのスタイル変更を含みます。

C:/npm_sample/src/components/ChildComponent.vue

<template>
  <div>
    <button class="messageButton" :disabled="isChildDisabled" @click="changeChildMessage">{{ buttonMessage }}</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isChildDisabled: false, // ボタンの非活性状態を管理するプロパティ
      buttonMessage: 'Vue',
    }
  },
  methods: {
    changeChildMessage() {
      this.$emit('change-message');
      this.isChildDisabled = true; // ボタンを非活性にする
      this.buttonMessage = 'プログラミング'; // ボタンのメッセージを更新
    }
  }
}
</script>

<style scoped>
.messageButton {
  background-color: #4CAF50;
  border: none;
  color: white;
  padding: 10px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  transition-duration: 0.4s;
  cursor: pointer;
  border-radius: 8px;
}

.messageButton:disabled {
  background-color: #e0e0e0;
  color: #a0a0a0;
  cursor: not-allowed;
}
</style>

<template>セクション

  • <div>: コンポーネントのHTMLマークアップをこのタグで囲みます。この例では、ボタンを含む単一の<div>要素のみが存在します。
  • <button>: ユーザーがクリックできるボタンです。このボタンには複数のVue固有の機能が使われています:
    • :disabled="isChildDisabled": disabled属性を、isChildDisabledデータプロパティの値に動的にバインドしています。これにより、isChildDisabledtrueの場合、ボタンは非活性化されます。
    • @click="changeChildMessage": ボタンがクリックされたときにchangeChildMessageメソッドを実行します。
    • {{ buttonMessage }}: ボタン上のテキストは、buttonMessageデータプロパティの値によって動的に決定されます。

<script>セクション

  • data()メソッド: コンポーネントの状態を管理するために使用されます。この例では、isChildDisabledbuttonMessageの2つのデータプロパティを定義しています。
  • methods: コンポーネント内で定義されたメソッド(関数)を含みます。この例では、changeChildMessageメソッドが定義されており、ボタンクリック時に以下のアクションを実行します:
    • 親コンポーネントへchange-messageイベントを発火します。これにより、親コンポーネントは子コンポーネントからのアクションに反応することができます。
    • isChildDisabledtrueに設定し、ボタンを非活性化します。
    • buttonMessageの値を'プログラミング'に更新し、ボタンのテキストを変更します。

<style scoped>セクション

  • このセクションは、コンポーネント特有のスタイルを定義します。scoped属性が付与されているため、これらのスタイルはこのコンポーネント内でのみ適用され、他のコンポーネントには影響を与えません。
  • .messageButton.messageButton:disabledは、それぞれ活性状態と非活性状態のボタンのスタイルを定義します。

コメント

タイトルとURLをコピーしました