Reputation: 4707
Never used Vue.js before. I have one parent component and 2 child components. These 2 child components should interact with asynchronous actions using the native Vue event bus system (with a dummy Vue object used as a shared container for the event bus).
Having something like the following:
EventBus.js
import Vue from "vue"
export default new Vue()
Parent.vue
import Child1 from "./Child1.vue"
import Child2 from "./Child2.vue"
export default {
name: "Parent",
components: {
child1: Child1,
child2: Child2,
}
}
Child1.vue
import EventBus from "./EventBus"
export default {
name: "Child1",
beforeCreate () {
EventBus.$once("MY_EVENT_X", async () => {
EventBus.$emit("MY_EVENT_Y")
})
},
mounted () {
// something
}
}
Child2.vue
import EventBus from "./EventBus"
export default {
name: "Child2",
beforeCreate () {
EventBus.$once("MY_EVENT_Y", async () => {
// do something
})
},
mounted () {
EventBus.$emit("MY_EVENT_X")
}
}
My question: having the events handlers defined in the "beforeCreate" hook, can I be sure that the "beforeCreate" hooks of both Child1 and Child2 components will be initiliazed before any of the "mounted" hooks of Child1 or Child2 will be called by Vue?
Upvotes: 1
Views: 198
Reputation: 22403
You can leverage component hook order between parent and children. When parent mounted
is called, we will be sure all child components is created and mounted.
Image source from here
To do it, you can define a boolean flag in parent, change this flag to true in mounted hook:
import Child1 from "./Child1.vue"
import Child2 from "./Child2.vue"
export default {
name: "Parent",
components: {
child1: Child1,
child2: Child2,
},
data: () => ({
isChildMounted: false
}),
mounted() {
this.isChildMounted = true
}
}
Make sure to pass this flag to children component:
<child-2 :isReady="isChildMounted" />
Finally, in child component, watching for props change. When the flag is changed to true, we know all child components is ready. It's time to emit event.
import EventBus from "./EventBus"
export default {
name: "Child2",
props: ['isReady'],
beforeCreate () {
EventBus.$once("MY_EVENT_Y", async () => {
// do something
})
},
watch: {
isReady: function (newVal) {
if (newVal) {
// all child component is ready
EventBus.$emit("MY_EVENT_X")
}
}
}
}
Upvotes: 2