0
votes

To avoid this becoming messy and the use of "native" jQuery/javascript I would like to call a function in the child component from the parent, the function I want to exeecute is change_map_data() from the child G_Map.vue in an elegant way, vueish way:

Parent.vue

<template>
<div class="col-md-12">
    ...
    <i v-on:click="change_map_data">change markers</i>
    ...
    <g-map v-bind:map_data="init_data.map"></g-map>
    ...
</div>
export default {
    data() {
        return {
            init_data: {
                map: {
                    map_ele: 'map'
                }
            }
        }
    }
}
</script>
</template>

G_Map.vue:

<template>
    <div :id="map_data.map_ele" class="gmap"></div>
</template>

<script>

import init_map from '../../../assets/js/map.js';

export default {

    props: ['map_data'],
    methods: {
        change_map_data: function() { // want to execute this from parent
            alert();
        }
    }
}
</script>
1
To answer properly, we need to know what causes the parent to make this call. There is probably some state in the parent that changes; that state could be sent to the child, which would watch it. - Roy J
@RoyJ, just a click, nothing has to change - Hula Hula
I question the need for this; one of the strengths of frameworks like this is that you deal with actionable events via property changes. If nothing had to change them why do you need to call a child method? - Dave Newton
@DaveNewton I think in this situation it would be better to eliminate the need to call change_map_data() on the child and just rely on the parent changing the bound map_data prop to change the map data (is this what you mean?). But there are some situations where you just want to make the child do something that has nothing to do with data binding at all. - Decade Moon
@DecadeMoon Understood, but personally, I'd still rather trigger workout reaching into independent components-less hoops, and cleaner ¯_(ツ)_/¯ - Dave Newton

1 Answers

3
votes

If you want to call a method defined on a child component from the parent component, you'll have to get a reference to the child component and call its method directly:

<i v-on:click="$refs.map.change_map_data()">change markers</i>
<g-map v-bind:map_data="init_data.map" ref="map"></g-map>

If you're generating a dynamic number of maps, then you'll need to do something like this:

<div v-for="map, i of maps">
  <i v-on:click="$refs.map[i].change_map_data()">change markers</i>
  <g-map v-bind:map_data="map" ref="map"></g-map>
</div>