Did you define the parent property in child component ?
Vue.js acces parent methods
I have a Vue object tied to a div and within that div i have a component. From the component I want to access methods of the parent. The child component contains buttons with handlers that should call methods from the parent.
<div id="parent">
<child-component></child-component>
</div>
I've found out that the parent can be accessed via vm.$parent but when i try to call a method like vm.$parent.someParentMethod() I get undefined... Any tips?
@bestmomo I'm not sure what you mean but I don't think so. The problem is that I will use the same component inside many different parent objects so I want to be able to access any parent the component might have.
@perkola Use props:
new Vue({
el: '#parent',
methods: {
first: function() {},
second: function() {},
another: function() {}
}
});
Vue.component('child-component', function() {
props: ['first', 'second', 'third'],
// the rest
});
// in your markup:
<div id="parent">
<child-component first=first second=second third=another></child-component>
</div>
@kfirba thanks I will try that soon! But is there a quick way to call a parent method from a component method?
new Vue({
el: '#parent',
methods: {
someParentMethod(data) {}
}
});
Vue.component('child-component', function() {
methods: {
someChildMethod() {
var data = 'test';
this.$parent.someParentMethod(data) // How do I call a parent method?
}
}
});
// Markup
<div id="parent">
<child-component></child-component>
</div>
@perkola I'm not aware to such thing. Try console.log() the this.$parent and see what attributes are exposed for your usage including methods and see if you can gain an access to the parent's attributes and methods. I still think that using the props is the best way to go about this.
Not the more elegant :
this.$parent.$options.methods.someParentMethod(data)
@perkola Another way is to not use hierarchy :
var vm = new Vue({
el: '#parent',
methods: {
someParentMethod(data) {}
}
});
Vue.component('child-component', function() {
methods: {
someChildMethod() {
var data = 'test';
vm.someParentMethod(data)
}
}
});
// Markup
<div id="parent">
<child-component></child-component>
</div>
@bestmomo with this approach I can't call a method on a generic parent. I want me component to call a method on the parent Vue without "knowing" which Vue. I might have parent1 and parent2 and i can't both name them vm :/
@perkola I think there is something weird that a child needs a parent function. Maybe you may use event system to achieve that.
@bestmomo I agree. I've read about Vue's event system but I can't figure out how to achieve what i described.
Vue's event system is simple. In child use a dispatch :
this.$dispatch('child-coucou', this);
And listen in parent :
this.$on('child-coucou', function (child) {
// Make something there with child reference
})
@bestmomo And how to pass data from nth child to root parent? Is there better way than this.$dispatch this.$on chaining?
@mkr I dont know another method and vue.js documentation doesn't mention one.
@bestmomo In 1.0.0-beta dispatch to root works fine, but not in -alpha
http://jsbin.com/poninazoku/edit?html,js,output
There are more seriuous changes vs 0.12
As much as a pita it might be i would look to remove anything not 1.x.x from your vue code.
I spent hours looking a components and events with 0.12.x and even the betas and ended up with an absolute mess. The official release just works. Using dispath and broadcast events.
Hardest part is building ghe hierarchy
If your parent is the root, you can use: this.$root.yourMethod()
I would go with using the event system. In your listeners, if you want the event to propagate upwards after the first response return true and the event propagation will not stop at the first response, going up the root.
//on the child. payload is just some data you want to pass along if any
...
this.$dispatch('childIsCalling', payload)
//on the parent(s). other parents up the chain (the parent's
//parent will also respond if true is returned
events: {
childIsCalling: function (payload) {
this.something = payload;
return true;
}
}
//or other wise
events: {
childIsCalling: 'handleChildCall'
}
methods: {
handleChildCall: function (payload) {
this.something = payload;
return true;
}
}
@belisar do you know if the disptach event can return a promise? It would be great to have $dispatch().then(do ...) ?
Thanks!
Just in case someone still finding an alternative
// Child component
Vue.component('child', {
props: ['label'],
template: `<button @click="$parent.someMethod">{{ label }}</button>`
});
// Parent component
const parent = vue({
el: '#app',
// Some codes
methods: {
someMethod () {
// do something.
}
}
})
The case, like this, when you have a parent, full with useful methods, whom you want to use in various children… I believe it's exactly the time to add a global store, like "vuex", into your app.
another way for vue 2
in child component use this.$emit('eventName'):
methods:{
openMenu(){
this.$emit('openMenu')
}
}
and in parent component use @eventName attribute:
<child @openMenu="main_menu=true"></child> // or call your method
yes, we have access to read the property of parent component using this.$parent, but do we have the access to change this property of parent component using this.$parent?
Please or to participate in this conversation.