J'ai un composant vue que j'utilise à l'intérieur de lui-même - les données peuvent avoir un tableau avec des sous-éléments et j'utilise ce tableau pour les rendre en boucle, et le niveau suivant, le niveau suivant, etc. selon le niveau d'imbrication.
Maintenant, je voudrais exécuter la méthode enfant à partir du parent, puis - si les instructions sont correctes, appelez-la également à l'enfant, au niveau suivant, etc.
J'utilise
<mycomponent
ref="myFirstLevelRefName"
(...)
></mycomponent>
et alors:
this.$refs.myFirstLevelRefName
d'appeler des enfants de premier niveau. Mais qu'en est-il des nœuds enfants? Je les utilise en vue de cette manière:
<mycomponent
v-for="(subElement, index) in getSubelements()"
ref="???"
v-bind:data="subElement"
v-bind:key="index"
></mycomponent>
J'ai essayé d'envoyer ceci. $ Refs du niveau enfant à la console, mais il est vide.
Comment dois-je définir le nom de référence dans les éléments imbriqués, puis les appeler à partir du parent?
Bien qu'il soit techniquement possible d'accéder à $refs
des enfants imbriqués ...
Vue.component('mycomponent', {
template: "#mycomponent",
});
new Vue({
el: '#app',
mounted() {
console.log(
'Second level <input>\'s value:',
this.$refs.myFirstLevelRefName.$refs.mySecondLevelRefName.value
)
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<template id="mycomponent">
<div>
<input ref="mySecondLevelRefName" value="Hello">
</div>
</template>
<div id="app">
<mycomponent ref="myFirstLevelRefName"></mycomponent>
</div>
Un moyen d'effectuer une communication parent/enfant profond, ou une communication profonde ancêtre/frère, pour des scénarios simples, consiste à utiliser un hub d'événements . (Pour les scénarios complexes, voir Vuex .)
Vous créeriez une variable globale:
var eventHub = new Vue(); // use a Vue instance as event hub
Pour émettre des événements que vous utiliseriez dans n'importe quel composant:
eventHub.$emit('myevent', 'some value');
Vous auriez alors, dans tout autre composant, à écouter cet événement. L'action de cet événement peut être n'importe quoi, y compris un appel de méthode (ce que vous voulez):
eventHub.$on('myevent', (e) => {
console.log('myevent received', e)
// this.callSomeMethod();
});
Démo:
var eventHub = new Vue(); // use a Vue instance as event hub
Vue.component('component-first', {
template: "#component-1st",
methods: {
myMethod() {
eventHub.$emit('myevent', 'some value');
}
}
});
Vue.component('component-second', {template: "#component-2nd"});
Vue.component('component-third', {
template: "#component-3rd",
created() {
eventHub.$on('myevent', (e) => {
this.check();
});
},
methods: {
check() {
console.log('check method called at 3rd level child');
}
}
})
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<template id="component-1st">
<div>
1st level component
<button @click="myMethod">Trigger event at 1st level component that will call 3rd level child's method</button>
<hr>
<component-second></component-second>
</div>
</template>
<template id="component-2nd">
<div>
<component-third></component-third>
</div>
</template>
<template id="component-3rd">
<div><h1>3rd level child</h1></div>
</template>
<div id="app">
<component-first></component-first>
</div>
Remarque: Si la création d'une instance dédiée en tant que hub d'événements est quelque chose de compliqué dans votre environnement, vous pouvez remplacer eventHub
par this.$root
(à l'intérieur de vos composants) et utilisez votre propre instance Vue comme hub.