J'essaie de faire fonctionner mon code qui ressemble à ce jsFiddle .
Le code a essentiellement onclick = "vm. $ Refs.foo.addThing ()"
en dehors de l'instance de Vue (je ne pouvais pas changer la façon dont il est) qui appelle une fonction dans le de Vue méthodes
.
Cependant, cela ne fonctionne pas pour le moment, et je ne comprends pas pourquoi c'est comme ça.
HomeView.vue
<div id="app"> <h1>Component Test</h1> <my-component ref="foo"></my-component> </div> <button onclick="vm.$refs.foo.addThing()">External Button</button>
HTML
var MyComponent = Vue.extend({ template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>', data: function() { return { things: ['first thing'] }; }, methods: { addThing: function() { this.things.push('another thing ' + this.things.length); } } }); var vm = new Vue({ el: '#app', components: { 'my-component': MyComponent } });
3 Réponses :
Vous pouvez exposer cette méthode à l'objet window
, mais c'est considéré comme un anti-pattern et vous devriez probablement envisager de déplacer ce bouton à l'intérieur du composant d'une manière ou d'une autre.
Ou utilisez un hack:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <h1>Component Test</h1> <my-component ref="foo"></my-component> </div> <button id="btn-external">External Button</button>
const MyComponent = Vue.extend({ template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>', data: function() { return { things: ['first thing'] }; }, methods: { addThing: function() { this.things.push('another thing ' + this.things.length); } } }); const vm = new Vue({ el: '#app', mounted() { var btn = document.getElementById('btn-external'); btn.addEventListener('click', this.$refs.foo.addThing); }, components: { 'my-component': MyComponent } });
Vous pouvez accéder à $ refs
avant que le modèle n'ait été traité (Vérifiez docs ).
Veuillez consulter le code révisé: https://jsfiddle.net/b5oset1w/17/
Javascript:
<div id="app"> <h1>Component Test</h1> <my-component ref="foo"></my-component> <button @click="onAddThing">External Button</button> </div>
Modèle:
var MyComponent = Vue.extend({ template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>', data: function() { return { things: ['first thing'] }; }, methods: { addThing: function() { this.things.push('another thing ' + this.things.length); } } }); var vm = new Vue({ el: '#app', components: { 'my-component': MyComponent }, mounted: function() { console.log(this.$refs) }, methods: { onAddThing: function() { this.$refs.foo.addThing() } } });
Une autre approche pour y parvenir consiste à créer également une instance de vue pour le bouton externe. comme l'exemple de code ci-dessous.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script> <div id="app"> <h1>Component Test</h1> <my-component ref="foo"></my-component> </div> <div id="newapp"> <button @click="clickAction">External Button</button> </div>
var MyComponent = Vue.extend({ template: '<div><p>Hello</p><ul><li v-for="thing in things">{{ thing }}</li></ul></div>', data: function() { return { things: ['first thing'] }; }, methods: { addThing: function() { this.things.push('another thing ' + this.things.length); } } }); var vm = new Vue({ el: '#app', components: { MyComponent: MyComponent } }); var vm1 = new Vue({ el: '#newapp', methods:{ clickAction:function(){ vm.$refs.foo.addThing(); } } });
À moins que vous n'ayez d'autres données et méthodes dans cette instance supplémentaire de Vue (à part le "bouton externe"), je ne pense pas que cela vaudrait toutes les ressources (par exemple, avoir pour passer par les crochets du cycle de vie complet) passé.
@ Andrew1325 Ne fonctionne pas car
est en dehors de l'instance de Vue, aka, dans le simple HTML (je ne peux pas changer la façon dont il est).
Curieusement, ce violon fonctionne très bien dans Codepen: codepen.io/tony19/pen/NeeEbm?editors = 1010
si vous liez votre fichier js à la fin du corps, ce problème peut ne pas se produire.