Search code examples
javascriptvue.jsvuejs2vue-componentvuex

How to send data to parent method from components?


I want to send parameters to parent method from component. But I got these error message "[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'deleteClicked' of undefined"

I want to send parameters to deleteClicked function from component.

My javascript code is below.

var sablon = Vue.extend({
    props: ["name"],
    template: '<button type="button" class="btn btn-warning" v-on:click=this.$parent.deleteClicked(name) style = "margin: 3px;" > {{ name }}</button > '
});

var viewmodel = new Vue({
    el: '#divimiz',
    components: { 'sablonx': sablon },
    data: {
        names: ['Mary', 'John', 'Robert'],
        newname: '',
        test: "selam",
    },
    methods: {
        addname: function () {
            this.names.push(this.newname);
            this.newname = '';
        },
        deleteClicked: function (item) {
            var x = this.names.indexOf(item);

            if (x > -1) {

                this.names.splice(x, 1);
            }
        },
    },

});

And my html code is below,

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<div id="divimiz" class="container">
    <div class="row">


    <sablonx v-for="name in names" v-bind:name="name"></sablonx>
    <br>

    <input class="form-control" type="text" v-model="newname" style="width: 400px; margin: 5px;">
    <button class="btn btn-info" v-on:click="addname">Click to add name</button>


</div>


<script src="x.js"></script>

Solution

  • You don't need to use the this keyword in your template.

    <button
      type="button"
      class="btn btn-warning"
      v-on:click="$parent.deleteClicked(name)"
      style="margin: 3px;">
      {{ name }}
    </button >
    

    Also, I recommand to use custom events to achieve what you want to do.

    <!-- Children component -->
    <button
      type="button"
      class="btn btn-warning"
      v-on:click="$emit('delete', name)"
      style="margin: 3px;">
      {{ name }}
    </button >
    
    <!-- Parent component -->
    <sablonx
      v-for="name in names"
      :key="name"
      :name="name"
      @delete="deleteClicked"/>
    

    You can see no params is passed visually to the function deleteClicked, but what actually happens is that it listens to the delete event, and will apply the data passed from the event to the function. Another way of writing it would be:

    <!-- Parent component -->
    <sablonx
      v-for="name in names"
      :key="name"
      :name="name"
      @delete="deleteClicked($event)"/>
    

    where $event is the variable containing the name you want to delete.