Llame a un método de componente Vue.js desde fuera del componente

Resuelto harryg asked hace 9 años • 17 respuestas

Digamos que tengo una instancia principal de Vue que tiene componentes secundarios. ¿Existe alguna forma de llamar a un método que pertenezca a uno de estos componentes desde fuera de la instancia de Vue por completo?

Aquí hay un ejemplo:

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>
Expandir fragmento

Entonces, cuando hago clic en el botón interno, el increaseCount()método está vinculado a su evento de clic, por lo que se llama. No hay forma de vincular el evento al botón externo, cuyo evento de clic estoy escuchando con jQuery, por lo que necesitaré otra forma de llamar increaseCount.

EDITAR

Parece que esto funciona:

vm.$children[0].increaseCount();

Sin embargo, esta no es una buena solución porque hago referencia al componente por su índice en la matriz secundaria y, con muchos componentes, es poco probable que esto permanezca constante y el código sea menos legible.

harryg avatar Nov 13 '15 05:11 harryg
Aceptado

Al final opté por utilizar la directiva de Vueref . Esto permite hacer referencia a un componente desde el padre para acceso directo.

P.ej

Tener un componente registrado en mi instancia principal:

const vm = new Vue({
    el: '#app',
    components: { 'my-component': myComponent }
});

Renderice el componente en plantilla/html con una referencia:

<my-component ref="foo"></my-component>

Ahora, en otro lugar puedo acceder al componente externamente.

<script>
  vm.$refs.foo.doSomething(); //assuming my component has a doSomething() method
</script>

Vea este violín para ver un ejemplo: https://jsfiddle.net/0zefx8o6/

(ejemplo antiguo usando Vue 1: https://jsfiddle.net/6v7y6msr/ )

Editar para Vue3 - API de composición

El componente secundario tiene returnla función que setupdesea utilizar en el componente principal; de lo contrario, la función no está disponible para el componente principal.

Nota: <script setup> el documento no está afectado porque proporciona todas las funciones y variables de la plantilla de forma predeterminada.

harryg avatar May 30 '2016 09:05 harryg

Puede configurar la referencia para los componentes secundarios y luego, en el padre, puede llamar a través de $refs:

Agregue referencia al componente secundario:

<my-component ref="childref"></my-component>

Agregar evento de clic al padre:

<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>
  <button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
</div>
  
<template id="my-template">
  <div style="border: 1px solid; padding: 2px;" ref="childref">
    <p>A counter: {{ count }}</p>
    <button @click="increaseCount">Internal Button</button>
  </div>
</template>
Expandir fragmento

Cong Nguyen avatar Dec 28 '2018 04:12 Cong Nguyen

Para Vue2 esto se aplica:

var bus = new Vue()

// en el método del componente A

bus.$emit('id-selected', 1)

// en el gancho creado del componente B

bus.$on('id-selected', function (id) {

  // ...
})

Consulte aquí los documentos de Vue. Y aquí hay más detalles sobre cómo configurar exactamente este bus de eventos.

Si desea obtener más información sobre cuándo usar propiedades, eventos y/o administración de estado centralizada, consulte este artículo .

Vea a continuación el comentario de Thomas sobre Vue 3.

musicformellons avatar Sep 10 '2017 20:09 musicformellons

Puedes usar el sistema de eventos Vue

vm.$broadcast('event-name', args)

y

 vm.$on('event-name', function())

Aquí está el violín: http://jsfiddle.net/hfalucas/wc1gg5v4/59/

Helder Lucas avatar Nov 12 '2015 23:11 Helder Lucas