Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

depsimon's avatar

Vue.js call component method from Vue instance

Hi, I'm pretty new to Vue.js and I'm struggling with this particular issue.

I made a counter components that get its value from the server. This component has an update() method that I call once in the ready section of my component.

In my Vue instance I'd like to call this same update() method from time to time, when I need to reload the counters.

For now all I could do is loop through this.$children and check if the $options.name was the counter component's and if it was the case, finally call the update() method.

I'm sure there is a more vue-way to achieve this, isn't it ?

Here's my code.

<pagination-counter source="{{ url('/pages/draft') }}"></pagination-counter>
var PaginationCounter = Vue.extend({
    props: ['source'],
    template: '<span class="label label-default pull-right">{{ count }}</span>',
    data: function() {
        return {
            count: 0
        };
    },
    ready: function() {
        this.update();
    },
    methods: {
        update: function() {
            this.$http.get(this.source, function(response) {
                this.count = response.total;
            });
        }
    }
});

Vue.component('pagination-counter', PaginationCounter);
var paginationApp = new Vue({
    el: "#pagination-app",
    data: {
        // 
    },
    ready: function() {
        //
    },
    methods: {
        fetchPage: function(page) {
            this.$http.get(page).then(function(response) {
                this.updateCounters();
            }, function(response) {
                // handle error
            });
        },
        updateCounters: function() {
            for (var i = 0; i < this.$children.length; i++) {
                if (this.$children[i].$options.name == 'pagination-counter') {
                    this.$children[i].update();
                }
            }
        }
    }
});
0 likes
10 replies
depsimon's avatar

I can't seem to figure out how to do this.

In my component I added :

    events: {
        'pagination-counter-refresh': function() {
            this.update();
        }
    }

And in my Vue instance I replaced the updateCounters method by this :

     updateCounters: function() {
            this.$dispatch('pagination-counter-refresh');
    },

But the update method is not triggered...

Sagaio's avatar
Sagaio
Best Answer
Level 2

I think you want to use $broadcast since your component is a child. $dispatch is used for sending data to parents. But then again, I might have misunderstood your code.

1 like
david.angenendt@gmx.de's avatar

i think i've got the same problem here. Could you please share your code? Would be great!

mwm's avatar

I know this is late @david.angenendt@gmx.de, but in case someone else is wondering, it's pretty simple/straightforward just change the $dispatch in the code posted the reply to $broadcast.

willvincent's avatar

Assuming you have this structure:

parent
 |
 +-- child
 |   |
 |   +-- grandchild
 |   +-- grandchild
 +-- child
 +-- child

To communicate from parent to child or grandchild, or child to grandchild, fire a $broadcast event, to communicate from child to parent, or grandchild to child use a $dispatch event. Broadcast moves down, dispatch moves up.

jimmck's avatar

Events are handy for things not directly coupled to each other. If I have a component created by my Vue instance I just store the instance when I initialize the instance.

    app = new Vue({
        el: '#app-container',
...
        data: {
            forms: {},
            forms1: {},
            that: null,
            comp: undefined,
            comp1: undefined,
            compTable: undefined,

...
            init: function() {
                fyi('Attaching Components...');
                //debugger;
                Vue.config.debug = true; // turn on debugging mode
                this.comp = this.$refs.cvglistbox;
                this.compTable = this.$refs.cvgtable;
                //this.comp.addSelectHandler(this.mySelectHandler);
                this.compTable
                    .addHeader('Description')
                    .addHeader('Id')
                    .setTblDiv();

Why clog your message stream with events no other part really cares about? And you can always use your component action methods as event handlers if you need to change.

DavidTorroija's avatar

@depsimon you need to use a new Vue instance only for the events this is the best way

var bus = new Vue({})


Object.defineProperty(Vue.prototype, '$bus', {
    get(){
        return this.$root.bus;
    },
    set(newInstance){
        this.$root.bus = newInstance;
    },
});

later in the parent child components

//parent
this.$bus.$emit('closeChild');
//child
this.$bus.$on('closeChild', ()=>{ 
//do something
});

source: https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

Please or to participate in this conversation.