1

I've been looking for solutions and references to my problems. I am confused to call a vue method (ex: createItem() {...}) that is inside the VueJs component via an external button.

Here my "app.js"

// ..\resources\assets\js\app.js
require('./bootstrap');

window.Vue = require('vue');
window.Vue.prototype.$http = axios;

Vue.component('sample', require('./components/SampleComponent.vue'));

const app = new Vue({
    el: '#app',
    methods: {
        createItem: function() {
            // what's here?
        }
    }
});

SampleComponent.vue

<template>
...
</template>

<script>
    export default {
        mounted() {
            this.getItems();
        },
        data() {
            return {
                items: [],
                newItem: {'name': '', 'description': ''},
                fillItem: {'id': '', 'name': '', 'description': ''}
            }
        },
        methods: {
            getItems() {
                axios.get( 'api/data' ).then( response => {
                    let answer = response.data;
                    this.items = answer;
                })
            },
            clearItem(){
                this.newItem = {'name': '', 'description': ''};
                this.fillItem = {'id': '', 'name': '', 'description': ''};
            },
            createItem(){
                var self = this;
                $("#create-role").on("hidden.bs.modal", function () {
                    self.clearItem();
                }).modal('show');
            },
        }
    }
</script>

index.blade.php

<div id="app>
...

<!-- Load samplecomponent to blade -->
<sample></sample>

<!-- An external button to call method inside SampleComponent.vue, How can I do this? -->
<button type="button" class="btn btn-sm" @click="createItem" id="external-button">Create new item</a>

</div> <!-- End App -->

I've read the guide, but it still fails. Sorry for this newbie question, I just used VueJS. Thank you for all the help.

lrfahmi
  • 120
  • 2
  • 10
  • It's a method call not a variable, hence: `@click="createItem()"` – ka_lin May 03 '18 at 08:08
  • Thanks @ka_lin, I want to call createItem() but via external button (outside component). – lrfahmi May 03 '18 at 08:15
  • First: the div did not close before the button, second: why? Technically you can access through the global `app` an make a regular JS on click event and you can use the `app` variable – ka_lin May 03 '18 at 08:17
  • If so it will appear like: [Vue warn]: Property or method "createItem" is not defined on the instance but referenced during render. As a reference question, I abbreviate the code, already fixed in question. – lrfahmi May 03 '18 at 08:22
  • Check [this](http://www.rent-a-hero.de/wp/2017/08/25/how-to-call-methods-of-a-vuejs-app-from-outside/) and [a clean way to comunicate between components](https://alligator.io/vuejs/component-communication/) – ka_lin May 03 '18 at 08:28
  • Thanks for the solution. I tried that solution, but it did not work. I have browsing several times do not find a solution. Though the meaning is simple: Call VueJS Method another external button. – lrfahmi May 03 '18 at 08:59
  • u need to use vue events ( emit or dispatch in vue1). vue events or global bus in order to comunicate across components. in adv u can use also vuex – Winston Fale May 03 '18 at 20:20

2 Answers2

0

Your markup is broken because the <button> is closed with </a> instead of </button>

<button ... @click="createItem" id="external-button">Create...</a>

Also, createItem is a function so make sure to add parentheses!

Corrected code:

<button type="button" class="btn btn-sm" @click="createItem()" id="external-button">Create new item</button>
Ben V.
  • 211
  • 1
  • 3
0

You could use a ref to call child's method:

Markup:

<div id="app>
  <sample ref="child"></sample>
  <button type="button" class="btn btn-sm" @click="callChildCreateItem" id="external-button">Create new item</a>
</div>

Parent:

const app = new Vue({
    el: '#app',
    methods: {
        callChildCreateItem: function() {
            this.$refs.child.createItem()
        }
    }
});

Or, you could use events (maybe a plugin like this make things easier)

Parent:

const app = new Vue({
    el: '#app',
    methods: {
        callChildCreateItem: function() {
             this.$events.fire('childCreateItem')
        }
    }
});

Child:

  export default {
        ...
        methods: {
           ...
            createItem(){
                ...
            },
        },
        events: {
          childCreateItem () {
            this.createItem()
          }
        },
    }

via: https://stackoverflow.com/a/47565763/965452

nachodd
  • 703
  • 6
  • 7