[Vuejs]-How to get onclick="vm.$refs.foo.addThing()" working in Vue when calling from external JS?

0πŸ‘

You could expose this method to the window object, but it’s considered an anti-pattern and you should probably consider moving this button inside of the component somehow.

Or, use some hack:

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
  }
});
<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>
πŸ‘€Yom T.

0πŸ‘

You can access $refs before the template has been processed(Check docs).

Please take a look at the revised code: https://jsfiddle.net/b5oset1w/17/

Javascript:

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

Template:

<div id="app">
  <h1>Component Test</h1>
  <my-component ref="foo"></my-component>

  <button @click="onAddThing">External Button</button>

</div>

0πŸ‘

another approach to achieve this is creating a vue instance for external button also. like below sample code.

    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();
        	}
        }
    });
<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>
πŸ‘€RAGINROSE

Leave a comment