How to Make a TODO CRUD App in Vue.js Full Tutorial for Beginners 2020

How to Make a TODO CRUD App in Vue.js Full Tutorial for Beginners 2020
  • Post author:
  • Post category:Vue
  • Post comments:0 Comments

 

Welcome folks today in this post we will making a todo app in vue.js 2020all the source code of the application is given below. A step by step youtube video is shown below.

 

 

Get Started

 

Create the Vue.js Project inside your project directory by the following command

 

vue create todoapp

 

Now go to the project Directory and run the following commands on command line

 

cd todoapp

 

npm run serve

 

Now your vue.js app will be started on port 8080

 

Now open the text editor and edit the App.vue file like this

 

<template>
  <div>
    <AddTodo/>
    <Todos/>
  </div>
</template>

<script>
import Todos from './components/Todos';
import AddTodo from './components/AddTodo'

export default {
  name: 'App',
  data(){
    return {
      todos:[
        {
          id:1,
          title:"todo 1",
          completed:false
        },
        {
          id:2,
          title:"todo 2",
          completed:true
        },
        {
          id:3,
          title:"todo 3",
          completed:false
        },
        {
          id:4,
          title:"todo 4",
          completed:true
        }
      ]
    }
  },
  components: {
    Todos,
    AddTodo
  },
</script>

 

 

Reading Todos

 

Now inside this App.vue we have included two custom components inside our template which is Todos component and the AddTodo component which will be responsible for adding a new Todo from a form.

Now inside your components folder you need to create these components.

Todos.vue

<template>
  <div>
    <div v-bind:key="todo.id" v-for="todo in todos">
      <TodoItem v-bind:todo="todo" />
    </div>
  </div>
</template>

<script>
import TodoItem from './TodoItem.vue';
export default {
  name: "Todos",
  components: {
    TodoItem
  },
  props: ["todos"]
}
</script>

<style scoped>
</style>

 

 

Here we are taking all the todos which are present and we are looping through it by using the v-for directive and here again we are using a custom component again which is TodoItem component

 

TodoItem.vue

 

<template>
  <div class="container">
  <div class="todo-item" v-bind:class="{'is-complete':todo.completed}">
    <p>
      <input type="checkbox" v-on:change="markComplete" v-bind:checked="todo.completed">
      {{todo.title}}
      <button class="del">x</button>
      </p>
  </div>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todo"],
  methods: {
    markComplete() {
      this.todo.completed = !this.todo.completed;
    }
  }
}
</script>

<style scoped>
  .todo-item {
    background: #f4f4f4;
    padding: 10px;
    margin:20px;
    border-bottom: 1px #ccc dotted;
  }

  .is-complete {
    text-decoration: line-through;
  }

  .del {
    background: #ff0000;
    color: #fff;
    border: none;
    padding: 5px 9px;
    border-radius: 50%;
    cursor: pointer;
    float: right;
  }
</style>

 

READ  Vue.js Toast Alert Push Notification Popup Bar in Browser Using HTML5 CSS3 and Javascript Full Project For Beginners

 

Now if you run the app it should look something like this as shown below

 

 

Now we need to create AddTodo component which will contain a simple form to submit a new Todo inside the app

 

AddTodo.vue

 

<template>
    <div class="container">
        <br>
        <h1 class="text-center">Todos App</h1>
        <br><br>
        <form>
        <div class="form-group">
            <input required type="text" v-model="title" placeholder="title" name="title" id="" class="form-control">
        </div>
        <div class="form-group">
            <button class="btn btn-block btn-danger">
                Add Todo
            </button>
        </div>
        </form>
    </div>
</template>
<script>

export default {
  name: "AddTodo",
  data() {
    return {
      title: ''
    }
  }
}
</script>

<style scoped>

</style>

 

 

Now if you run the app you will see the form also

 

 

Adding Todo

 

Now we will be adding a new Todo inside the app by making the form work. To do that we will be adding a @submit directive to the form like this

 

<form @submit="addTodo">
        <div class="form-group">
            <input required type="text" v-model="title" placeholder="title" name="title" id="" class="form-control">
        </div>
        <div class="form-group">
            <button class="btn btn-block btn-danger">
                Add Todo
            </button>
        </div>

 

 

Now we need to define this function which will execute once the form submits. Now inside the script section copy paste this code

 

export default {
  name: "AddTodo",
  data() {
    return {
      title: ''
    }
  },
  methods: {
    addTodo(e) {
        e.preventDefault()
      const newTodo = {
        id:Date.now(),
        title: this.title,
        completed: false
      }
      // Send up to parent
      this.$emit('add-todo', newTodo);

      this.title = '';
    }
  }
}

 

 

So now inside this we are making a new Todo from the values which are submitted namely id which is auto generated by using the Date function and the title of the todo and a third property completed which is default set to false

Now after that we are emitting a new event add-todo which will automatically go to the parent element in this case App.vue So now we need to catch this event which is passed from the child component

READ  Vue.js Render PDF Documents Using vue-pdf Library Full Tutorial with Examples

 

<AddTodo v-on:add-todo="addTodo"/>

 

Here we are using a special directive v:on to get the event which is sent and now we have defined a custom method AddTodo which will be executed to add a Todo

 

App.vue

 

addTodo(newTodo){
      this.todos = [...this.todos,newTodo]
    }

 

 

Deleting Todos

 

Now we will be using the same concept to delete the todos as well for this go to the TodoItem.vue file and make some changes like below

 

TodoItem.vue

 

<button @click="$emit('del-todo', todo.id)" class="del">x</button>

 

 

So here we are assigning a button click listener by using @click and we are emitting the event del-todo

So now we need to catch this in Todos.vue file

 

Todos.vue

 

<TodoItem v-bind:todo="todo" v-on:del-todo="$emit('del-todo', todo.id)" />

 

 

And now again we need to emit this in App.vue parent component like this

 

App.vue

 

<Todos v-bind:todos="todos" v-on:del-todo="deleteTodo"/>

 

 

Now we need to define this custom function deleteTodo which will be executed to actually delete the todo from the todos array

 

deleteTodo(id){
      this.todos = this.todos.filter((todo) => todo.id !== id)
    }

 

 

Now inside this block of code we are using the es6 high order function filter to delete the todo from the array.

 

Full Source Code

 

App.vue

 

<template>
  <div>
    <AddTodo v-on:add-todo="addTodo"/>
    <Todos v-bind:todos="todos" v-on:del-todo="deleteTodo"/>
  </div>
</template>

<script>
import Todos from './components/Todos';
import AddTodo from './components/AddTodo'

export default {
  name: 'App',
  data(){
    return {
      todos:[
        {
          id:1,
          title:"todo 1",
          completed:false
        },
        {
          id:2,
          title:"todo 2",
          completed:true
        },
        {
          id:3,
          title:"todo 3",
          completed:false
        },
        {
          id:4,
          title:"todo 4",
          completed:true
        }
      ]
    }
  },
  components: {
    Todos,
    AddTodo
  },
  methods:{

    addTodo(newTodo){
      this.todos = [...this.todos,newTodo]
    },
    deleteTodo(id){
      this.todos = this.todos.filter((todo) => todo.id !== id)
    }
  }
};
</script>

 

 

AddTodo.vue

 

<template>
    <div class="container">
        <br>
        <h1 class="text-center">Todos App</h1>
        <br><br>
        <form @submit="addTodo">
        <div class="form-group">
            <input required type="text" v-model="title" placeholder="title" name="title" id="" class="form-control">
        </div>
        <div class="form-group">
            <button class="btn btn-block btn-danger">
                Add Todo
            </button>
        </div>
        </form>
    </div>
</template>
<script>

export default {
  name: "AddTodo",
  data() {
    return {
      title: ''
    }
  },
  methods: {
    addTodo(e) {
        e.preventDefault()
      const newTodo = {
        id:Date.now(),
        title: this.title,
        completed: false
      }
      // Send up to parent
      this.$emit('add-todo', newTodo);

      this.title = '';
    }
  }
}
</script>

<style scoped>

</style>

 

READ  Build a Vue.js Image Silder With Fading Animation Using vue-image-slider Library Full Project For Beginners

 

Todos.vue

 

<template>
  <div>
    <div v-bind:key="todo.id" v-for="todo in todos">
      <TodoItem v-bind:todo="todo" v-on:del-todo="$emit('del-todo', todo.id)" />
    </div>
  </div>
</template>

<script>
import TodoItem from './TodoItem.vue';
export default {
  name: "Todos",
  components: {
    TodoItem
  },
  props: ["todos"]
}
</script>

<style scoped>
</style>

 

 

TodoItem.vue

 

<template>
  <div class="container">
  <div class="todo-item" v-bind:class="{'is-complete':todo.completed}">
    <p>
      <input type="checkbox" v-on:change="markComplete" v-bind:checked="todo.completed">
      {{todo.title}}
      <button @click="$emit('del-todo', todo.id)" class="del">x</button>
      </p>
  </div>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todo"],
  methods: {
    markComplete() {
      this.todo.completed = !this.todo.completed;
    }
  }
}
</script>

<style scoped>
  .todo-item {
    background: #f4f4f4;
    padding: 10px;
    margin:20px;
    border-bottom: 1px #ccc dotted;
  }

  .is-complete {
    text-decoration: line-through;
  }

  .del {
    background: #ff0000;
    color: #fff;
    border: none;
    padding: 5px 9px;
    border-radius: 50%;
    cursor: pointer;
    float: right;
  }
</style>

 

 

DOWNLOAD SOURCE CODE

 

Leave a Reply