J'ai deux composants imbriqués, quel est le moyen approprié d'accéder aux méthodes enfant à partir du parent?
this.$children[0].myMethod()
semble faire l'affaire mais il est plutôt moche, n'est-ce pas, quelle meilleure façon de faire:
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
Étant donné qu'une instance racine Vue est accessible par tous les descendants via this.$root
, un composant parent peut accéder aux composants enfants via le tableau this.$children
et un composant enfant peut accéder à son parent via this.$parent
, votre premier réflexe pourrait être d'accéder directement à ces composants.
La documentation de VueJS met en garde contre cela spécifiquement pour deux très bonnes raisons:
L'interface événementielle implémentée par Vue vous permet de communiquer de haut en bas de l'arborescence des composants. En exploitant l’interface d’événement personnalisée, vous avez accès à quatre méthodes:
$on()
- vous permet de déclarer un auditeur sur votre instance Vue avec laquelle écouter des événements$emit()
- vous permet de déclencher des événements sur la même instance (auto)$on()
et $emit()
:const events = new Vue({}),
parentComponent = new Vue({
el: '#parent',
ready() {
events.$on('eventGreet', () => {
this.parentMsg = `I heard the greeting event from Child component ${++this.counter} times..`;
});
},
data: {
parentMsg: 'I am listening for an event..',
counter: 0
}
}),
childComponent = new Vue({
el: '#child',
methods: {
greet: function () {
events.$emit('eventGreet');
this.childMsg = `I am firing greeting event ${++this.counter} times..`;
}
},
data: {
childMsg: 'I am getting ready to fire an event.',
counter: 0
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script>
<div id="parent">
<h2>Parent Component</h2>
<p>{{parentMsg}}</p>
</div>
<div id="child">
<h2>Child Component</h2>
<p>{{childMsg}}</p>
<button v-on:click="greet">Greet</button>
</div>
Réponse tirée du message d'origine: Communication entre composants dans VueJS
Vous pouvez utiliser ref .
import ChildForm from './components/ChildForm'
new Vue({
el: '#app',
data: {
item: {}
},
template: `
<div>
<ChildForm :item="item" ref="form" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.$refs.form.submit()
}
},
components: { ChildForm },
})
Si vous n'aimez pas le couplage étroit, vous pouvez utiliser Event Bus comme indiqué par @Yosvel Quintero. Vous trouverez ci-dessous un autre exemple d’utilisation d’un bus d’événement en lui passant comme accessoire.
import ChildForm from './components/ChildForm'
new Vue({
el: '#app',
data: {
item: {},
bus: new Vue(),
},
template: `
<div>
<ChildForm :item="item" :bus="bus" ref="form" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.bus.$emit('submit')
}
},
components: { ChildForm },
})
Code de composant.
<template>
...
</template>
<script>
export default {
name: 'NowForm',
props: ['item', 'bus'],
methods: {
submit() {
...
}
},
mounted() {
this.bus.$on('submit', this.submit)
},
}
</script>
https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/