カツオ @SpringBootとVue.jsでWebサービス開発中

起業、転職、サラリーマン生活、Webサービス、アプリ、働き方、プログラミング、Java、JavaScript

javascript vue.js

【vue.js】コンポーネント間のメソッドの呼び出し|親から子(ref)、子から親(emit)

投稿日:

Vue.jsで別コンポーネントに定義しているメソッドの呼び出し方についてメモしておきたいと思います。別コンポーネントの呼び出しは大きく2つ存在します。

  1. 親から子(ref)
  2. 子から親(emit)

最初にサンプルの動作イメージです。

  • 親が子どもに小遣いをあげる。(親から子に金額を渡します:ref)
  • 子が親の財布からお金を盗る笑。(子から親に金額を渡します:emit)

①親から子のコンポーネントの呼び出し(ref)

属性を渡すだけでしたらpropsが使えるのですが、子のコンポーネントに記述のあるメソッドを呼び出す場合はrefがとても便利です。親からすると、自分のコンポーネントに記載があるメソッドと同じような記述で子のコンポーネントを呼び出すことができます。

親コンポーネント「parent」

<template>
<div>
<h2>親</h2>
<p><button @click="callChildMethod01">子ども呼び出し①</button></p>
<p>
<input type="text" v-model="kozukai">円
<button @click="callChildMethod02">小遣いをあげる</button>
</p>
<child-app ref="taro"></child-app>
</div>
</template>
<script>
import childApp from './childApp.vue'
export default {
data () {
return {
kozukai: 0
}
},
components: {
childApp
},
methods: {
callChildMethod01 () {
this.$refs.taro.child_method_01()
},
callChildMethod02 () {
this.$refs.taro.child_method_02(this.kozukai)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

 

子どものコンポーネント「childApp」

<template>
<div>
<h2>子ども</h2>
おこずかい:{{number}}円
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
number: 0
}
},
methods: {
child_method_01 () {
alert('親から呼ばれました')
},
child_method_02 (tmp) {
this.number = this.number + parseInt(tmp)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

ポイント

  • 【親】template内の子コンポーネント呼び出しの際に「ref」で名前を追加している。例では「taro」。
<child-app ref="taro"></child-app>
  • 【親】子どもの中のメソッドをrefを使って呼び出す
methods: {
callChildMethod01 () {
this.$refs.taro.child_method_01()
},
callChildMethod02 () {
this.$refs.taro.child_method_02(this.kozukai)
}
}

この部分。01は引数なし、02は引数ありの例です。

  • 【子】子の側はとくに追加の記載は必要なし。

こんな感じです。親の中で子のコンポーネントを呼び出す際に「ref」で名前を追加するだけで、refを使って子のコンポーネントを呼び出すことができます。

②子から親のコンポーネントの呼び出し(emit)

こちらはemitを使います。emitの利用イメージですが、子から親に対してイベントを通知し、親側でイベントをハンドリングして処理を行うイメージです。子から発火するイベントにはパラメータを渡すことも可能です。

親コンポーネント

<template>
<div>
<h2>親</h2>
お財布の中身:{{money}}
<p><button @click="callChildMethod01">子ども呼び出し①</button></p>
<p>
<input type="text" v-model="kozukai">円
<button @click="callChildMethod02">小遣いをあげる</button>
</p>
<hr>
<child-app ref="taro"
@callParent="callFromChild"
@stealMoney="stealMoney"
></child-app>
</div>
</template>
<script>
import childApp from './childApp.vue'
export default {
data () {
return {
money: 10000,
kozukai: 0
}
},
components: {
childApp
},
methods: {
callChildMethod01 () {
this.$refs.taro.child_method_01()
},
callChildMethod02 () {
this.money = this.money - this.kozukai
this.$refs.taro.child_method_02(this.kozukai)
this.kozukai = 0
},
callFromChild () {
alert('子どもから親が呼ばれました。')
},
stealMoney (tmp) {
this.money = this.money - tmp
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

 

子コンポーネント

<template>
<div>
<h2>子ども</h2>
<p>おこずかい:{{money}}円</p>
<p><button @click="call_parent01">親を呼ぶ</button></p>
<p><input type="text" v-model="kingaku">円<button @click="call_parent02">親の財布から盗る</button></p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
money: 0,
kingaku: 0
}
},
methods: {
child_method_01 () {
alert('親から子どもが呼ばれました。')
},
child_method_02 (tmp) {
this.money = this.money + parseInt(tmp)
},
call_parent01 () {
this.$emit('callParent')
},
call_parent02 () {
this.$emit('stealMoney', this.kingaku)
this.money = this.money + parseInt(this.kingaku)
this.kingaku = 0
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

ポイント

  • 【子】親のメソッドを呼び出したいタイミングでemitを使って親にイベントを通知します。
call_parent01 () {
this.$emit('callParent')
},
call_parent02 () {
this.$emit('stealMoney', this.kingaku)
this.money = this.money + parseInt(this.kingaku)
this.kingaku = 0
}

 

02はパラメータも渡す例です。

  • 【親】emitで渡されたイベントをハンドリングします。
<child-app ref="taro"
@callParent="callFromChild"
@stealMoney="stealMoney"
></child-app>

template内のchild-appの呼び出しにイベントをバインドする記述を追加すればOK。

さいごに

こんな感じで簡単にコンポーネント間のメソッドの呼び出しが、親⇒子、子⇒親の双方向で簡単に実装できました。簡単なのはいいのですが、直観に任せて呼び出しを実装していくと、プログラム全体が迷路のように複雑になりかねないなと感じ、コーディングのルール決めみたいなのが重要なんだろうなと感じました。

vue.jsは日々勉強しながらWebサービス作っていますので、またメモにまとめていきたいと思います。

-javascript, vue.js

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

【Vue.js】ファイルアップロード(複数ファイル)の渡し方(axios)

Vue.jsをつかって開発をやっています。画像アップロードを作りたくて、この2日くらい色々調べながら実装をしていました。ようやくそれなりに動くものができましたので、せっかっくなのでブログにも記載させて …

【Vue.js】ドラッグアンドドロップの実装方法(vuedraggable)

vue.jsでドラッグアンドドロップの実装ですが、「vuedraggable」を利用することで優れたUIを簡単に実装することができます。 vuedraggableの使い方については以下サイトがとても丁 …

【Vue.js】サーバーに公開する方法(ビルド手順)

作ったプロジェクトをサーバーに配置する方法です。この手順ですと静的リソースとしてローカルでjavascript、cssをビルドしてくれますので、安いレンタルサーバーとかでも動作します。私も昔から使って …

【vue.js】画像ファイルのアドレスの指定方法について【vuetify】

assets配下に格納している画像ファイルの指定方法についてちょっとつまって調べました。個人的によく忘れちゃうので画像などの静的リソースの指定方法についてメモしておきます。 imgタグの場合 < …

no image

Javascriptでソート処理の実装(jQuery・カスタムデータ属性)

jQueryを使ったシンプルなソート機能のサンプルです。 こん感じでリスト要素があった時に、ボタンクリックで並び替え(ソート)処理を行います。 ※イメージのみです。動きません。 ソート 山田 鈴木 田 …