Reputation: 996
I am using Vue.Js v2. I want to call component1->c1method in component2->c2method for reload data after submitting.
Vue.component('component1', {
methods: {
c1method: function(){
alert('this is c1method')
},
}
})
Vue.component('component2', {
methods: {
c2method: function(){
component('component1').c1method()//like this
},
}
})
Upvotes: 81
Views: 165875
Reputation: 49
For those looking > 2024 vue 3 composition.
// child
const emit = defineEmits(['close_chat']);
const close_chat = () => {
emit('close_chat');
};
//parent
import ChatBot from './components/chatbot.vue';
const close_chat = () => {
console.log('closed');
}
// <ChatBot @close_chat="close_chat"></ChatBot>
Upvotes: 0
Reputation: 391
With Vue3 you need to:
Parent component:
<template>
<ChildComponent @created="handleCreate" />
</template>
export default {
methods: {
handleCreate() {
console.log('Child has been created.');
}
}
}
Child Component:
// ChildComponent
export default {
created() {
this.$emit('created');
}
}
Upvotes: 1
Reputation: 742
I found a good solution for Vue 3 in this SO question and answer https://stackoverflow.com/a/72348802/18091372
It uses Vue3's defineExpose function to make an internal function available outside of the component.
If you have a structure like this in ComponentA
<template>
<div>
<ComponentB ref="componentb" />
</div>
</template>
where ComponentB
has:
<script setup>
defineExpose( {internal_function} )
function internal_function() {
console.log( 'hello' )
}
</script>
then, ComponentA
can do:
<script setup>
const componentb = ref(null)
componentb.value.internal_function()
</script>
and hello
will be logged to the console.
Upvotes: 3
Reputation: 51
If anyone is looking for a solution in Vue.js v3:
https://v3-migration.vuejs.org/breaking-changes/events-api.html#event-bus
https://github.com/developit/mitt#install
import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )
// fire an event
emitter.emit('foo', { a: 'b' })
// clearing all events
emitter.all.clear()
Upvotes: 5
Reputation: 15992
The docs address this situation
https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
If your components have the same parent, you can emit an event that the parent listens to. Then with the ref
property set, you can call the c1method
from the parent.
https://v2.vuejs.org/v2/guide/components.html#Child-Component-Refs
Upvotes: 19
Reputation: 793
No need for hacky solutions.
In vuejs we can create events that can be listened globally.
With this feature, whenever we want to call our beloved function, we just emit this event.
Now, we just listen to this event all the time from the component. whenever this global event happens we can execute our method we want to call.
It's pretty simple:
export const eventBus = new Vue(); // added line
new Vue({
...
...
...
render: h => h(App)
}).$mount('#app');
eventBus.$emit('fireMethod');
created() {
eventBus.$on('fireMethod', () => {
this.myBelovedMethod();
})
}
Dont forget to import eventBus in top.
import {eventBus} from "path/to/main.js";
thats it, few lines of code, no hacky, all vuejs power.
Upvotes: 26
Reputation: 1045
For non-parent-child relation, then this is the same as this one. Call one method, apparently any method of a component from any other component. Just add a $on
function to the $root
instance and call form any other component accessing the $root
and calling $emit
function.
On First component
.... mounted() { this.$root.$on('component1', () => { // your code goes here this.c1method() } }
and in the second component call the $emit
function in $root
... c2method: function(){ this.$root.$emit('component1') //like this },
It acts more like a socket. Reference here
https://stackoverflow.com/a/50343039/6090215
Upvotes: 72
Reputation: 2800
// Component A
Vue.component('A', {
created() {
this.$root.$refs.A = this;
},
methods: {
foo: function() {
alert('this is A.foo');
}
}
});
// Component B
Vue.component('B', {
methods: {
bar: function() {
this.$root.$refs.A.foo();
}
}
});
Upvotes: 58
Reputation: 837
Try this out.
<template>
...
<component1 ref='componentOne'>
...
</template>
<script>
Vue.component('component2', {
methods: {
c2method: function(){
this.$refs.componentOne.c1method();
}
}
});
</script>
Upvotes: 14