1
votes

Comment faire fonctionner onclick = "vm. $ Refs.foo.addThing ()" dans Vue lors d'un appel depuis un JS externe?

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 commentaires

@ Andrew1325 Ne fonctionne pas car

3 Réponses :


0
votes

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
  }
});


0 commentaires

0
votes

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()
    }
  }
});


0 commentaires

0
votes

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();
        	}
        }
    });


1 commentaires

À 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é.