Reputation: 10345
I just started experimenting with Vue.js
I try to implement crud operations in a Todo app using Vue.js
My code fails to delete a todo item
The deletion of a todo item is implemented in the parent class
<template>
<div>
<p>Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p>
<p>Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p>
// we are now passing the data to the todo component to render the todo list
<todo v-for="todo in todos" v-bind:todo="todo" v-bind:key="todo.id"></todo>
</div>
</template>
<script type = "text/javascript" >
import Todo from './Todo';
export default {
props: ['todos'],
components: {
Todo,
},
methods: {
completeTodo(todo) {
const todoIndex = this.todos.indexOf(todo);
this.todos[todoIndex].done = true;
},
deleteTodo(todo) {
const todoIndex = this.todos.indexOf(todo);
this.todos.splice(todoIndex, 1);
},
},
};
</script>
The delete action is an event on the child class, which should trigger the delete action in the parent
<template>
<div class='ui centered card'>
// Todo shown when we are not in editing mode.
<div class="content" v-show="!isEditing">
<div class='header'>
{{ todo.title }}
</div>
<div class='meta'>
{{ todo.project }}
</div>
<div class='extra content'>
<span class='right floated edit icon' v-on:click="showForm">
<i class='edit icon'></i>
</span>
/* add the trash icon in below the edit icon in the template */
<span class='right floated trash icon' v-on:click="deleteTodo(todo)">
<i class='trash icon'></i>
</span>
</div>
</div>
// form is visible when we are in editing mode
<div class="content" v-show="isEditing">
<div class='ui form'>
<div class='field'>
<label>Title</label>
<input type='text' v-model="todo.title" />
</div>
<div class='field'>
<label>Project</label>
<input type='text' v-model="todo.project" />
</div>
<div class='ui two button attached buttons'>
<button class='ui basic blue button' v-on:click="hideForm">
Close X
</button>
</div>
</div>
</div>
<div class='ui bottom attached green basic button' v-on:click="changeStatus(todo)" v-show="!isEditing && todo.done" disabled>
Completed
</div>
<div class='ui bottom attached red basic button' v-on:click="completeTodo(todo)" v-show="!isEditing && !todo.done">
Pending
</div>
</div>
</template>
<script>
export default {
props: ['todo'],
data() {
return {
isEditing: false,
};
},
methods: {
showForm() {
this.isEditing = true;
},
hideForm() {
this.isEditing = false;
},
completeTodo(todo) {
this.$emit('complete-todo', todo);
},
changeStatus(todo){
todo.done = !todo.done;
},
deleteTodo(todo) {
this.$emit('delete-todo', todo);
},
},
};
</script>
Upvotes: 0
Views: 48
Reputation: 211
<todo v-for="todo in todos" v-bind:todo="todo" v-bind:key="todo.id" @delete-todo="deleteTodo" @ complete-todo="completeTodo"></todo>
try this
Upvotes: 1
Reputation: 543
You need to add v-on:complete-todo="completeTodo"
and v-on:deleteTodo="deleteTodo"
to your <todo>
s.
( or @complete-todo="completeTodo"
instead of v-on:
if you are using Vue3, your Todo.vue
also needs a list of events that this component can propagate
emits: ['delete-todo', 'complete-todo'],
Upvotes: 1