Skip to main content

Todo List App with VueJS





VueJS is a modern Javascript framework that makes it easy to handle data flow, simply by including attributes in your HTML tags.

In this guide, we'll be building a simple todo list app to get up and running with VueJS.

Setup and Installation

There are two ways to setup Vue: through a NodeJS project, or by including a script inside of your HTML file. Since we're just starting out, we'll use a script inside of our index.html file.

We can set up our index.html file like this.

<!DOCTYPE  html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todooey - A Simple Todo List App</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
    </div>
  </body>
</html>

In order to use Vue in our app, we need to create a new instance of Vue. We can do this using another script tag before the closing body tag.

<script>
  new Vue( {
    el: '#app',
  });
</script>

Now, we're able to use Vue in our app!

Creating Our App

Before we add the functionality to our app with Vue, we'll create the basic HTML/CSS structure with static content.

Inside of our HTML file, we'll create the Add Todo input, as well as the Todo list and each item

<div class="container">
  <h1 class="">My Todo List</h1>
  <div class="card">
    <div class="flex">
      <input placeholder="Add new todo" />
        <button>Add</button>
    </div>
  </div>
  <div class="card">
    <div class="card-inner">
      <h2>Todo</h2>
      <ul class="list">
        <li class="list-item">
          <div class="list-item-toggle"></div><span>Wash the car</span>
          <div class="list-item-delete">X</div>
        </li>
      </ul>
    </div>
  </div>
</div>

Then, we'll add some basic styling to our app inside our style.css file.

html,
body {
  margin: 0;
  padding: 0;
  background: #faffff;
  font-size: 16px;
}

* {
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
        Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  color: #3d4855;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-top: 0;
}

.container {
  padding: 24px 0;
  max-width: 700px;
  width: 100%;
  margin: 0 auto;
}

.card {
  border-radius: 4px;
  box-shadow: 1px 1px 40px -10px #31505f30, 0px 1px 2px 0px #31505f30;
  background: white;
  margin-bottom: 24px;
}

.card-inner {
  padding: 16px 24px;
}

.flex {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

input {
  border-radius: 4px;
  background: transparent;
  border: none;
  width: 100%;
  padding: 14px;
  font-size: 16px;
  border: 1px solid transparent;
  height: 100%;
  display: block;
  outline: none;
}

button {
  background: #4fc08d;
  padding: 10px 22px;
  border: none;
  color: white;
  border-radius: 4px;
  margin: 8px;
  font-size: 16px;
  cursor: pointer;
  box-shadow: 1px 1px 15px -2px #212c4430;
  transition: 0.15s;
}

button:hover {
  background: #42aa7b;
}

button:disabled {
  background: #e8e8e8;
  color: #555;
  box-shadow: none;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list-item {
  padding: 12px 16px 12px 16px;
  border: 1px solid #e8e8e8;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-bottom: 6px;
  border-radius: 4px;
}

.list-item:first-child {
  border-top: 1px solid #e8e8e8;
}

.list-item-toggle {
  border: 1px solid #e8e8e8;
  border-radius: 999px;
  height: 21px;
  width: 21px;
  margin-right: 16px;
}

.list-item-delete {
  margin-left: auto;
  color: tomato;
  margin-top: -2px;
  font-weight: bold;
  text-decoration: none !important;
}

.list-item.completed {
  border: 1px solid #4fc08d;
}

.list-item.completed span {
  text-decoration: line-through;
}

.list-item.completed .list-item-toggle {
  background: #4fc08d;
  border: #4fc08d;
}

Using Vue to Add Functionality

Great! Now that our app is styled, we can begin using Vue to create a dynamic todo list.

Displaying Our Todo List

To display our todo list, we'll take advantage of Vue's 2-way data flow. Inside of our script tag, we'll use Vue's data object to create an array that will contain all our todo items.

<script>
  new Vue( {
    el: '#app',
    data: {
      items: [
         {
           id: 1,
           name: 'Clean the fridge'
         },
         {
           id: 2,
           name: 'Walk the dogs'
         },
      ]
    }
  });
</script>

Each todo item has a name and an ID, which will be used for removing items from the list later on.

Now that we have our data, we can display it in our list using the v-for attribute, which is basically a forEach loop that Vue uses.

<ul class="list">
  <li class="list-item" v-for="item in reversedItems">
    ...
    <span>{{ item.name }}</span>
    ...
  </li>
</ul>

Using the v-for attribute allows us to acces the item property. We can display the name by using the double handlebars syntax: {{ item.name }}.

Adding Todo Items

Now that our items display properly, we can work on adding new items to the list. Using Vue's methods property, we can create a method that adds a new todo to the list.

First, let's create a new property inside our data object, called newItem.

<script>
  new Vue( {
    el: '#app',
    data: {
      newItem: '',
      items: [...]
    }
  });
</script>

This will be the value that we enter into the Add Todo input.

In order to make sure that what we type in our input updates the newItem value, we can take advantage of Vue's 2-way data flow, using the v-model attribute. This means that whatever value we enter into the input will be persisted to the dataobject.

<input v-model="newItem" placeholder="Add new todo"  />

Since we now have our newItem value stored, we can create a method to add that item to the list.

Beneath the data object, we'll create a new methods object with a function, addItem.

<script>
  new Vue( {
    el: '#app',
    data: {...},
    methods: {
      addItem: function() {
        this.items.push({
          id: this.items.length + 1,
          name: this.newItem,
          completed: false,
        });
        this.newItem = '';
      },
    },
  });
</script>

Basically, when this function is called, we're taking the newItem value and pushing it to the items array. The, we're clearing out the newItem value, which clears our Add Todo input.

Now, all we need to do is call the function when we click the Add button. We can use the v-on attribute, or the @ symbol for short.

<button @click="addItem">Add</button>

Now, Vue will know to call the addItem function when this button is clicked.

As something a little extra, we can also disable the button is there is no value in the input, using the :disabled attribute. This tells Vue to apply the disabled attribute only if the expression inside the qoutes is true.

<button @click="addItem" :disabled="newItem.length === 0">Add</button>

Marking Items as Complete

The final thing that we need to do is add the ability to mark our items as complete.

To do this, we'll add a new property to each item in our array: the completedproperty.

<script>
new Vue({
  el: '#app',
  data: {
    items: [{
      id: 1,
      name: 'Clean the fridge',
      completed: true,
    },
    {
      id: 2,
      name: 'Walk the dogs',
      completed: false,
    }]
  }
});
</script>

Vue once again provides us with an attribute to dynamically change the class of an element, based on data in the Vue instance.

So, we can go to our list item and add the :class attribute.

<li class="list-item" :class="{completed: item.completed}" v-for="item in reversedItems">
  ...
</li>

This tells Vue that it should apply the completed class to the <li> only if the item is completed (which we can tell by accessing the item.completed property.

Now, our completed items should have a green outline. However, we still need to be able to mark them complete if they are not.

To do this, we'll create another method, called toggleComplete.

<script>
  new Vue( {
    el: '#app',
    data: {...},
    methods: {
      addItem: function() {...},
      toggleComplete: function (item) {
        item.completed = !item.completed;
      }
    },
  });
</script>

Once we have our method, we can call it using the @click attribute that Vue provides.

<li class="list-item" :class="{completed: item.completed}" v-for="item in reversedItems">
  <div class="list-item-toggle" @click="toggleComplete(item)"></div>
  ...
</li>

Once again, we can pass in the item object as a prop to the function, because Vue allows us to access it via the v-for attribute.

Now, we can toggle each todo item between complete and uncomplete.

Deleting Todo Items

The final thing we need to do is allow ourselves to delete todo items. Once again, we'll use a method to accomplish this.

<script>
  new Vue( {
    el: '#app',
    data: {...},
    methods: {
      addItem: function() {...},
      toggleComplete: function (item) {...},
      removeItem: function (itemID) {
        this.items = this.items.filter((item) => newItem.id!== itemID);
      } 
    },
  });
</script>

In this function, we're accessing the itemID prop (which is passed from the delete element) and setting the items property to a new array, without the item we just deleted.

Now, we can call the function from our delete element.

<li class="list-item" :class="{completed: item.completed}" v-for="item in reversedItems">
  ...
  <div class="list-item-delete" @click="removeItem(item.id)">X</div>
</li>

Tada! Now, we can succesfully delete our todo items!

Final Thoughts

So that's it! We've just build a functioning todo application using Vue. We learned how to call methods, access data and update data, all without any JS DOM manipulation.

Comments

Popular posts from this blog

Php Interview Questions

1. What Is PHP ? 2. How can I disable the output of error messages inside the HTML page? 3. Can I return other file formats (like Word, Excel, etc) using PHP? 4. Is there any way to force PHP to do garbage collection before the end of the request? 5. Why does require($file_name) in a loop just include the first file repeatedly? 6. Can you include and call C libraries in PHP scripts? How? 7. What's the best way to start writing a PHP program? 8. Passing variables with REQUIRE function (part II) 9. I use a /cgi-bin/ad.pl for displaying rotating banners at the top of my html files. How can I insert the output of this cgi in an "included" file ? 10. please tell me how to let a html document read content from a .txt file, spit this out in a table, and how to update the specific file with a form 11. How can I add authentication to my site with PHP? I have authentication working only with one page. 12. Where can I get documentation for the Zend API? 13....

5 Significant Reasons For Having A Good Website For Your Business

In this era, where everything is now available online, and people are becoming more and more Internet dependant, any company needs to have a well-built website. People tend to check any company online before getting any service from them. A well-built website will help to make you a good impression on your consumers, and they will gain reliability on you. A well-maintained site is the essence of a good company, and without a website, you will fail to make that vital first impression on your customers. It would be best if you also used   website promotion   to promote your website. The certain benefits of having a website are mentioned below. Accessible: A website makes your business available to people 24*7. People can search your website anytime they want and visiting your website will provide them with relevant information that they are looking for. If you hire a  responsive   web design company ,  then you can be sure of your website to make an excell...

Laravel CRUD With MongoDB

Laravel is the most popular framework of php. laravel better than another PHP framework because it handles the command base. so let us see about laravel 8 MongoDB CRUD tutorial example. it was released on Sept 03, 2019. Now, we follow the below step for creating the laravel 8 MongoDB CRUD operation(Laravel 8 CRUD example). Overview Step 1: Install Laravel 8 Step 2: Configure MongoDB database Step 3: Install laravel-mongodb Package Step 4: Add Route Step 5: Create Model and Controller Step 6: Create Blade Files Step 1: Install Laravel 8 We are going to install laravel 8, so first open the command prompt or terminal and go to xampp htdocs folder directory using the command prompt. after then run the below command. 1 composer create-project --prefer-dist laravel/laravel laravel8_crud_mongodb Step 2: Configure MongoDB database After the complete installation of laravel. we have to database configuration. now we will open the .env file and add the MONGO_DB_HOST, MONGO_DB_PORT, MONGO_DB_DATA...