Call VueJS component function from HTML DOM button using refs

Example to trigger VueJS component method from outside: directly in DOM HTML or in Vue.

by RomainMazB

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<html>
  <body class="bg-dark text-light">
    <div id="app" class="container">
      <div class="row">
        <h3>External buttons</h3>
      </div>
      <div class="row">
        <button @click="addThingTo('component1')" class="btn btn-outline-success btn-sm mr-2">External Button 1</button>
        <button @click="addThingTo('component2')" class="btn btn-outline-success btn-sm mr-2">External Button 2</button>
        <button @click="addThingTo('component3')" class="btn btn-outline-success btn-sm mr-2">External Button 3</button>
      </div>
      <div class="row">
        <h3>Components</h3>
      </div>
      <div class="row">
        <my-component ref="component1" class="col sm-3"></my-component>
        <my-component ref="component2" class="col sm-3"></my-component>
        <my-component ref="component3" class="col sm-3"></my-component>
      </div>
    </div>
  </body>
</html>

JavaScript

var MyComponent = Vue.extend({
  template: '<div><button id="externalButton" @click="addThing()" class="btn btn-outline-primary btn-large btn-block">Internal Button </button><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
  },
  methods: {
  	addThingTo(component) {
    	this.$refs[component].addThing();
    }
  }
});