Ref y event bus tienen problemas cuando su renderizado de control se ve afectado por v-if. Entonces, decidí ir con un método más simple.
La idea es usar una matriz como cola para enviar métodos que deben llamarse al componente secundario. Una vez que se montó el componente, procesará esta cola. Observa la cola para ejecutar nuevos métodos.
(Tomando prestado un código de la respuesta de Desmond Lua)
Código del componente principal:
import ChildComponent from './components/ChildComponent'
new Vue({
el: '#app',
data: {
item: {},
childMethodsQueue: [],
},
template: `
<div>
<ChildComponent :item="item" :methods-queue="childMethodsQueue" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.childMethodsQueue.push({name: ChildComponent.methods.save.name, params: {}})
}
},
components: { ChildComponent },
})
Este es el código para ChildComponent
<template>
...
</template>
<script>
export default {
name: 'ChildComponent',
props: {
methodsQueue: { type: Array },
},
watch: {
methodsQueue: function () {
this.processMethodsQueue()
},
},
mounted() {
this.processMethodsQueue()
},
methods: {
save() {
console.log("Child saved...")
},
processMethodsQueue() {
if (!this.methodsQueue) return
let len = this.methodsQueue.length
for (let i = 0; i < len; i++) {
let method = this.methodsQueue.shift()
this[method.name](method.params)
}
},
},
}
</script>
Y hay mucho margen de mejora, como pasar processMethodsQueuea un mixin ...