web-dev-qa-db-fra.com

Appeler une méthode de composant Vue.js depuis l'extérieur du composant

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.

123
harryg

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/ )

168
harryg

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/

22
Helder Lucas

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 .

15
musicformellons

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>

4
Cong Nguyen

Voici un simple

this.$children[indexOfComponent].childsMethodName();
0
Pratik Khadtale

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');
   }
}
0
Dotnetgang

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>
0
Victor