LoginSignup
5
5

More than 3 years have passed since last update.

vueのクリックイベントで、子のイベントを親に渡す方法。

Last updated at Posted at 2020-10-26

Vueのクリックイベントで子のイベントを親に引き継ぐ方法。

(子テンプレートのボタンをクリックしたときに、親テンプレートで定義しているメソッドを実行する方法)

設定手順

子:①クリックイベントを設定 @click=$emit('イベント名')
  ↓
親:②子のイベントを受け取る (子のタグ内で設定したイベント名)
  ↓
親:③methodsに処理を記述

・子から親にイベントを引き継ぐ。
$emit  子から親へのデータ/イベント受け渡し
@click  v-on:click の省略形


記述例

・用意するファイルは2つ
親:parent.vue
子:TmpBtn.vue

・実現したいこと
親で呼び出した小テンプレートのボタンをクリックしたときに、親テンプレートで設定してあるメソッドを実行する。

(子)TmpBtn.vue
<template>
    <v-btn
    elevation="2"
    rounded
    width="20%"
    //①クリックイベントを設定
    @click="$emit('child-click')"
    >
    ボタン
    </v-btn>
</template>

子テンプレートのボタンがクリックされると、child-clickというイベントを親に渡す。

(親)parent.vue
<template>
  <v-app>
    <TmpBtn
  <!--②子のイベントを受け取る-->
    @child-click="BtnClicked(hello)"
    />
  </v-app>
</template>

<script>
import TmpBtn from "./TmpBtn"

export default {
  components:{
    TmpBtn
  },
  data(){
    return{
      hello:"親テンプレートのメソッドを実行"
    }
  },
  methods:{
    //③methodsに処理を記述
    BtnClicked(a){
      console.log(a)
    }
  }
}
</script>

子テンプレートのボタンがクリックされたら、BtnClickedメソッドを実行する。

▼実行例
image.png

image.png

子テンプレートのボタンクリックで、親テンプレートで設定したイベントの発火に成功。


$emitしないとどうなるか

$emitしない場合、イベント設定は2種類考えられる。

  1. 子テンプレートにclickイベントとメソッドを記述 → OK
  2. 親テンプレートにclickイベントとメソッドを記述 → NG

上記の場合、正常に作動するのは1のみ
2の親テンプレートで呼び出した子テンプレートタグにclickイベントを設定しても動作しない。


子テンプレートに記述する場合

<template>
    <v-btn
    elevation="2"
    rounded
    width="20%"
    @click="ChildClicked(child)"
    >
    ボタン
    </v-btn>
</template>

<script>
export default {
  methods:{
    ChildClicked(a){
      console.log(a)
    }
  },
  data(){
    return{
      child:"子テンプレートのボタンがクリックされました"
    }
  }
}
</script>

image.png

正常に作動。

親テンプレートに記述する場合

(親)parent.vue
<template>
  <v-app>
    <TmpBtn
    :bind="text"
    <!--子テンプレートを呼び出し、クリックイベントを設定-->
    @click="BtnClicked(hello)"
    />
  </v-app>
</template>

<script>
import TmpBtn from "./TmpBtn"

export default {
  components:{
    TmpBtn
  },
  data(){
    return{
     hello:"親テンプレートのメソッドを実行"
    }
  },
  methods:{
    BtnClicked(a){
      console.log(a)
    }
  }
}
</script>

image.png

反応なし。。

親テンプレートに記述したメソッドを実行する場合は下記2パターンで検討する必要がある。

①子からイベントを引き継ぐ
②親テンプレート内にボタンを作成したクリックイベントを設定する


イベント情報を渡す ($event)

変数$eventを使うことで、クリックした画面上の位置情報などを渡すことができる。

(子)TmpBtn.vue
<template>
    <v-btn
    elevation="2"
    rounded
    width="20%"
    <!--clickイベントの引数で$eventを渡す-->
    @click="$emit('chiled-clicked', $event)"
    >
    ボタン
    </v-btn>
</template>
(親)parent.vue
<template>
  <v-app>
    <TmpBtn
    <!--子テンプレのイベントを受け取り、メソッドを実行-->
    @chiled-clicked="BtnClicked(hello, $event)"
    />
    <br>
  </v-app>
</template>

<script>
import TmpBtn from "./TmpBtn"

export default {
  name: "Parent",
  components:{
    TmpBtn
  },
  data(){
    return{
      hello:"親テンプレートのメソッドを実行"
    }
  },
  methods:{
    //第2引数に$eventを渡す
    BtnClicked(a, b){
      console.log(a)
      console.log(b)
    }
  }
}

▼実行結果
image.png

$eventの中身
MouseEvent {isTrusted: true, screenX: 77, screenY: 151, clientX: 77, clientY: 17, …}
isTrusted: true
screenX: 77
screenY: 151
clientX: 77
clientY: 17
ctrlKey: false
shiftKey: false
altKey: false
metaKey: false
button: 0
buttons: 0
relatedTarget: null
pageX: 77
pageY: 17
x: 77
y: 17
offsetX: 61
offsetY: 10
movementX: 0
movementY: 0
fromElement: null
toElement: span.v-btn__content
layerX: 61
layerY: 9
view: Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
detail: 1
sourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}
which: 1
type: "click"
target: span.v-btn__content
currentTarget: null
eventPhase: 0
bubbles: true
cancelable: true
defaultPrevented: false
composed: true
timeStamp: 132300.8249999839
srcElement: span.v-btn__content
returnValue: true
cancelBubble: false
path: (8) [span.v-btn__content, button.v-btn.v-btn--rounded.theme--light.elevation-2.v-size--default, div.v-application--wrap, div#app.v-application.v-application--is-ltr.theme--light, body, html, document, Window]
__proto__: MouseEvent



$event内の特定のデータが欲しい場合はプロパティを指定する。

  methods:{
    BtnClicked(a, b){
      console.log(b.type)
    }
  }

//出力
//click
5
5
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
5
5