Llame a un método de componente Vue.js desde fuera del componente
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>
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.
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 return
la función que setup
desea 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.
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>
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.
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/