###やりたいこと
- v-forの中で子コンポーネントを複数作る
- 親コンポーネントからそれぞれの子コンポーネントのメソッドを呼びたい
###前提
親コンポーネントから子コンポーネントのメソッドを呼びたい時、$refsを使えば可能です。
App.vue
//親コンポーネント
<template>
<div id="app">
<button @click="callChildMethod">Change Message</button>
<!-- 子コンポーネントにref属性を付けて参照出来るようにする -->
<HelloWorld ref="child"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
methods: {
callChildMethod(){
//子コンポーネントのメソッドを呼ぶ
this.$refs.child.changeMsg();
}
},
components: {
HelloWorld
}
}
</script>
HelloWorld.vue
//子コンポーネント
<template>
<div class="hello">
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Hello!'
}
},
methods: {
changeMsg(){
this.msg = 'Hi!';
}
}
}
</script>
###v-for内の場合
しかし、v-for内でこの手法を使おうとするとUncaught TypeError: this.$refs.child.changeMsg is not a function
とエラーが出てしまいます。
App.vue
<template>
<div id="app">
<!-- 子コンポーネントをv-forで複数個作る -->
<div v-for="n in 3" :key="n">
<button @click="callChildMethod">Change Message</button>
<HelloWorld ref="child"/>
</div>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
methods: {
callChildMethod(){
this.$refs.child.changeMsg();
//→Uncaught TypeError: this.$refs.child.changeMsg is not a function
}
},
components: {
HelloWorld
}
}
</script>
###対処法
その場合はv-for
の引数として提供されているindexを渡してあげれば解決します。
App.vue
<template>
<div id="app">
<!-- v-forの引数でindexを指定 -->
<div v-for="(n, index) in 3" :key="n">
<!-- メソッドにindexを渡す -->
<button @click="callChildMethod(index)">Change Message</button>
<HelloWorld ref="child"/>
</div>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
export default {
name: 'App',
methods: {
callChildMethod(index){
//this.$refs.参照ID[index].子のメソッド()の形で呼ぶ
this.$refs.child[index].changeMsg();
}
},
components: {
HelloWorld
}
}
</script>
###注意点
ただしコンポーネント同士が密結合になってしまい良くないので、あくまで小規模なものの中で使うようにして、大規模なものに関してはvuexを使うようにした方が後々幸せになれるかもしれません。
###参考
https://laracasts.com/discuss/channels/vue/child-and-refs-not-a-function