2
votes

I just started learning Vue and I got some problems with passing events through different components. I'm building a simple todo list app with basic functionalities like adding new tasks and deleting them. This is the link to the repo https://github.com/Polenj86/vue-taskmanager.

The tree structure of my app is:

-root //App.vue
-- childcomponent // NewTask.vue
-- childcomponent // TasksWrapper.vue
   -- grandchildcomponent //Task.vue

What I'm trying to achieve is to give a button to Task.vue that let me delete a task from the tasks array in the root. By now I only managed to delete the task by clicking on the entire element with this method:

<app-component @click.native="deleteTask"></app-component>

methods: {
  deleteTask(index) {
    this.tasks.splice(index, 1)
  }
}

What I want is to give this method to the button inside the component and not to the entire component.

This is the grandchildren code:

<template lang="pug">
.panel.panel-default
    .panel-body
        slot(name="task-content")
    .panel-footer
        button.btn.btn-sm.btn-primary(@click="deleteTask") Delete task

</template>    

How can I inform the root I want to delete this? I tried to use an event emitter but I don't get what should I pass as a second argument in the emitter.

export default {    
    methods: {
        deleteTask() {
            this.$emit('taskWasDeleted', ???);
        }
    }
}

Thanks for help

1

1 Answers

2
votes

Since the Task,vue is not a direct child of App.vue you can use a global EventBus

In your main.js file create an empty Vue instance as a central event bus:

export const EventBus = new Vue();

Now pass the index from v-for to Task.vue component as a prop

//grandChild component or Task.vue
<app-component :taskIndex="index" :key="index"></app-component>

in your Task.vue emit an event passing the index as second paramater that you received as a prop

<template lang="pug">
.panel.panel-default
    .panel-body
        slot(name="task-content")
    .panel-footer
        button.btn.btn-sm.btn-primary(@click="deleteTask") Delete task

</template>  

import {EventBus} from './main.js'
export default {    
    proos: ['tabIndex'],
    methods: {
        deleteTask() {
            EventBus.$emit('deleteTask', this.tabIndex);
        }
    }
} 

Now in the App.vue in the created hook listeb for the deleteTask event

//App.vue
<script>
import {EventBus} from './main.js'
export default{
    created(){
        EventBus.$on('deleteTask', (taskIndex) => {
            this.tasks.splice(taskIndex, 1)
        });
    }
}
</script> 

` Here is the fiddle