Reputation: 13162
I have 4 component
My component first like this :
<template>
...
<component-second></component-second>
...
</template>
<script>
...
export default {
...
updated() {
// call check method in the component fourth
}
}
</script>
My component second like this :
<template>
...
<component-third></component-third>
...
</template>
<script>
...
export default {
...
}
</script>
My component third like this :
<template>
...
<component-fourth></component-fourth>
...
</template>
<script>
...
export default {
...
}
</script>
My component fourth like this :
<template>
...
</template>
<script>
...
export default {
...
methods: {
check() {
...
}
}
}
</script>
So, if update() in component first executed, I want to call check method in the component fourth
How can I do it?
Upvotes: 1
Views: 3058
Reputation: 1448
What I would try is to create a data element in the parent method and pass it along its children, then watch it in the component-four
and on change of its value trigger the check method.
<template>
...
<component-second update-flag="updateFlag"></component-second>
...
</template>
<script>
...
export default {
data(){
return {
updateFlag: true;
}
}
updated() {
// call check method in the component fourth
updateFlag = !updateFlag;
}
}
</script>
Component-second:
<template>
...
<component-third update-flag="updateFlag"></component-third>
...
</template>
<script>
...
export default {
...
props: ['updateFlag']
}
</script>
Component third:
<template>
...
<component-fourth update-flag="updateFlag"></component-third>
...
</template>
<script>
...
export default {
...
props: ['updateFlag']
}
</script>
Component fourth:
<template>
...
</template>
<script>
...
export default {
...
props: ['updateFlag'],
watch: {
updateFlag: function (val) {
this.check();
}
},
methods: {
check() {
...
}
}
}
</script>
Upvotes: 1
Reputation: 135742
You can use a Vue instance as event bus.
You would create a global variable:
var eventHub = new Vue(); // use a Vue instance as event hub
To emit events you would use in any component:
eventHub.$emit('myevent', 'some value');
And, to listen to that event, again, in any component, do:
eventHub.$on('myevent', (e) => {
console.log('myevent received', e)
});
Demo:
var eventHub = new Vue(); // use a Vue instance as event hub
Vue.component('component-first', {
template: "#component-first-tpl",
data() { return {someFlag: true} },
updated() {
eventHub.$emit('myevent', 'some value');
}
});
Vue.component('component-second', {
template: "#component-second-tpl"
});
Vue.component('component-third', {
template: "#component-third-tpl"
});
Vue.component('component-fourth', {
template: "#component-fourth-tpl",
created() {
eventHub.$on('myevent', (e) => {
console.log('myevent received', e)
this.check();
});
},
methods: {
check() {
console.log('check called at fourth');
}
}
})
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
<script src="https://unpkg.com/vue"></script>
<template id="component-first-tpl">
<div>
<component-second></component-second>
<br>
someFlag: {{ someFlag }}
<button @click="someFlag = !someFlag">Trigger update</button>
</div>
</template>
<template id="component-second-tpl">
<div>
<component-third></component-third>
</div>
</template>
<template id="component-third-tpl">
<div>
<component-fourth></component-fourth>
</div>
</template>
<template id="component-fourth-tpl">
<div><h1>I'm Number 4</h1></div>
</template>
<div id="app">
<p>{{ message }}</p>
<component-first></component-first>
</div>
Note: If creating a dedicated instance as event hub is something complicated in your environment, you can replace eventHub
with this.$root
(inside your components) and use your own Vue instance as hub.
Upvotes: 5