Disons que j'ai une instance principale de Vue qui a des composants enfants. Existe-t-il un moyen d'appeler une méthode appartenant à l'un de ces composants en dehors de l'instance de Vue?
Voici un exemple:
var vm = new Vue({
el: '#app',
components: {
'my-component': {
template: '#my-template',
data: function() {
return {
count: 1,
};
},
methods: {
increaseCount: function() {
this.count++;
}
}
},
}
});
$('#external-button').click(function()
{
vm['my-component'].increaseCount(); // This doesn't work
});
<script src="http://vuejs.org/js/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app">
<my-component></my-component>
<br>
<button id="external-button">External Button</button>
</div>
<template id="my-template">
<div style="border: 1px solid; padding: 5px;">
<p>A counter: {{ count }}</p>
<button @click="increaseCount">Internal Button</button>
</div>
</template>
Ainsi, lorsque je clique sur le bouton interne, la méthode increaseCount()
est liée à son événement click, de sorte qu'elle est appelée. Il n’existe aucun moyen de lier l’événement au bouton externe dont j’écoute l’événement de clic avec jQuery. Il me faut donc un autre moyen d’appeler increaseCount
.
MODIFIER
Il semble que cela fonctionne:
vm.$children[0].increaseCount();
Cependant, ce n'est pas une bonne solution car je référence le composant par son index dans le tableau d'enfants et, avec de nombreux composants, il est peu probable que cela reste constant et que le code soit moins lisible.
En fin de compte, j'ai choisi d'utiliser la directive ref
de Vue . Cela permet à un composant d'être référencé à partir du parent pour un accès direct.
Par exemple.
Avoir un compenent inscrit sur mon instance parent:
var vm = new Vue({
el: '#app',
components: { 'my-component': myComponent }
});
Rendez le composant dans template/html avec une référence:
<my-component ref="foo"></my-component>
Maintenant, ailleurs, je peux accéder au composant à l'extérieur
<script>
vm.$refs.foo.doSomething(); //assuming my component has a doSomething() method
</script>
Voir ce violon pour un exemple: https://jsfiddle.net/xmqgnbu3/1/
(ancien exemple utilisant Vue 1: https://jsfiddle.net/6v7y6msr/ )
Vous pouvez utiliser le système d'événements Vue
vm.$broadcast('event-name', args)
et
vm.$on('event-name', function())
Voici le violon: http://jsfiddle.net/hfalucas/wc1gg5v4/59/
Depuis Vue2, ceci s'applique:
var bus = new Vue()
// dans la méthode du composant A
bus.$emit('id-selected', 1)
// dans le hook créé du composant B
bus.$on('id-selected', function (id) {
// ...
})
Voir ici pour les documents Vue. Et ici est plus détaillée sur la façon de configurer ce bus d’événements exactement.
Si vous souhaitez plus d'informations sur l'utilisation des propriétés, des événements et/ou de la gestion d'état centralisée, voir cet article .
Vous pouvez définir ref pour les composants enfants, puis dans parent peut appeler via $ refs:
Ajouter une référence au composant enfant:
<my-component ref="childref"></my-component>
Ajouter un événement de clic au parent:
<button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
var vm = new Vue({
el: '#app',
components: {
'my-component': {
template: '#my-template',
data: function() {
return {
count: 1,
};
},
methods: {
increaseCount: function() {
this.count++;
}
}
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<my-component ref="childref"></my-component>
<br>
<button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
</div>
<template id="my-template">
<div style="border: 1px solid; padding: 5px;" ref="childref">
<p>A counter: {{ count }}</p>
<button @click="increaseCount">Internal Button</button>
</div>
</template>
Voici un simple
this.$children[indexOfComponent].childsMethodName();
C'est un moyen simple d'accéder aux méthodes d'un composant à partir d'un autre composant.
// This is external shared (reusable) component, so you can call its methods from other components
export default {
name: 'SharedBase',
methods: {
fetchLocalData: function(module, page){
// .....fetches some data
return { jsonData }
}
}
}
// This is your component where you can call SharedBased component's method(s)
import SharedBase from '[your path to component]';
var sections = [];
export default {
name: 'History',
created: function(){
this.sections = SharedBase.methods['fetchLocalData']('intro', 'history');
}
}
Une version légèrement différente (plus simple) de la réponse acceptée:
Avoir un compenent inscrit sur l'instance parent:
export default {
components: { 'my-component': myComponent }
}
Rendez le composant dans template/html avec une référence:
<my-component ref="foo"></my-component>
Accéder à la méthode du composant
<script>
this.$refs.foo.doSomething();
</script>