Learning Vue Part 2: Building a to-do app

WHAT TO KNOW - Sep 8 - - Dev Community

<!DOCTYPE html>





Learning Vue Part 2: Building a To-Do App

<br> body {<br> font-family: sans-serif;<br> margin: 0;<br> padding: 20px;<br> }</p> <div class="highlight"><pre class="highlight plaintext"><code> h1, h2, h3 { margin-top: 30px; } pre { background-color: #f0f0f0; padding: 10px; border-radius: 5px; overflow-x: auto; } code { font-family: monospace; } .container { display: flex; flex-direction: column; align-items: center; } .todo-list { list-style: none; padding: 0; } .todo-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } .todo-item input { margin-right: 10px; } .todo-item button { background-color: #007bff; color: #fff; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer; } </code></pre></div> <p>



Learning Vue Part 2: Building a To-Do App



In our previous article, we were introduced to the basics of Vue.js. We learned about components, data binding, and how to create simple interactive elements. In this installment, we'll build a more comprehensive application: a To-Do App. This project will solidify our understanding of Vue's core concepts and introduce us to more advanced features like:



  • Component Structure:
    Breaking down the app into reusable components.

  • Data Management:
    Using Vuex for efficient data management.

  • Dynamic Lists:
    Rendering lists of items with Vue.js.

  • User Interaction:
    Implementing actions like adding, editing, and deleting tasks.




Setting Up the Project



To begin, we'll set up a new Vue project using the Vue CLI. If you haven't already, install the Vue CLI globally on your system:


npm install -g @vue/cli


Then, create a new Vue project with the following command:


vue create to-do-app


Select the default preset (Babel, ESLint) and wait for the project to be created. Navigate to the project directory:


cd to-do-app


Project Structure



The basic structure of our To-Do App will consist of the following components:


  • App.vue: The main application component that will hold other components.
  • TodoList.vue: A component responsible for displaying and managing the list of tasks.
  • TodoItem.vue: A reusable component to represent individual to-do items.


We'll create a new folder named 'components' inside the 'src' folder to house our components. The file structure will look like this:


to-do-app/
  ├── src/
  │   ├── App.vue
  │   ├── components/
  │   │   ├── TodoList.vue
  │   │   └── TodoItem.vue
  │   └── main.js
  ├── ...


Creating the Components


  1. App.vue

The App.vue component will be our main container. It will hold the TodoList component:

  <template>
   <div id="app">
    <todolist>
    </todolist>
   </div>
  </template>
  <script>
   import TodoList from './components/TodoList.vue';

export default {
  name: 'App',
  components: {
    TodoList,
  }
};
  </script>

  1. TodoList.vue

The TodoList component is responsible for managing the list of tasks. It will display the tasks, handle user input for adding new tasks, and allow editing/deleting existing ones.

  <template>
   <div class="container">
    <h1>
     To-Do List
    </h1>
    <input @keyup.enter="addTask" placeholder="Add new task..." type="text" v-model="newTask"/>
    <ul class="todo-list">
     <todoitem :key="index" :task="task" @delete-task="deleteTask" @update-task="updateTask" v-for="(task, index) in tasks">
     </todoitem>
    </ul>
   </div>
  </template>
  <script>
   import TodoItem from './TodoItem.vue';

export default {
  name: 'TodoList',
  components: {
    TodoItem,
  },
  data() {
    return {
      newTask: '',
      tasks: [],
    };
  },
  methods: {
    addTask() {
      if (this.newTask.trim() !== '') {
        this.tasks.push({
          text: this.newTask,
          completed: false,
        });
        this.newTask = '';
      }
    },
    updateTask(task, index) {
      this.tasks[index] = task;
    },
    deleteTask(index) {
      this.tasks.splice(index, 1);
    },
  },
};
  </script>

  1. TodoItem.vue

The TodoItem component is a reusable component for displaying individual tasks. It allows marking tasks as completed and deleting them.

  <template>
   <li class="todo-item">
    <input type="checkbox" v-model="task.completed"/>
    <span :class="{ 'completed': task.completed }">
     {{ task.text }}
    </span>
    <button @click="$emit('delete-task')">
     Delete
    </button>
   </li>
  </template>
  <script>
   export default {
  name: 'TodoItem',
  props: {
    task: {
      type: Object,
      required: true,
    },
  },
  methods: {
    updateTask() {
      this.$emit('update-task', this.task);
    },
  },
};
  </script>


Explaining the Code

  • App.vue: The main component, responsible for rendering the TodoList component.
    • TodoList.vue:
    • v-model: Used to bind the input field's value to the newTask data property. This creates two-way data binding, updating the data when the input changes and vice versa.
    • @keyup.enter: Triggers the addTask method when the user presses the Enter key while the input field is focused.
    • v-for: Creates a new TodoItem component for each task in the tasks array.
    • 🔑 Provides a unique key for each TodoItem, which is essential for Vue to efficiently update the list when items are added or removed.
    • :task: Passes the task object as a prop to the TodoItem component.
    • @update-task: Listens for the 'update-task' event emitted by the TodoItem component and calls the updateTask method.
    • @delete-task: Listens for the 'delete-task' event emitted by the TodoItem component and calls the deleteTask method.
    • TodoItem.vue:
    • props: The task prop is required and represents the data for the individual task.
    • v-model: Binds the checkbox to the task.completed property.
    • :class: Dynamically adds the 'completed' class to the task text if the task.completed property is true.
    • $emit: Emits the 'update-task' event when the task is updated, passing the updated task data.
    • $emit: Emits the 'delete-task' event when the delete button is clicked.

      Running the Application

      With the components in place, you can run the application using:

npm run serve


This will start the development server, and you can access the app in your browser at http://localhost:8080/. You should now be able to add tasks, mark them as complete, and delete them.



Adding Vuex for Data Management



Currently, the tasks array is stored directly within the TodoList component. This approach works for small applications, but as the app grows, it becomes challenging to manage data across multiple components. For better data management, we'll introduce Vuex.



Vuex is a state management library specifically designed for Vue.js. It provides a centralized store for all components to access and modify data. This allows for more organized and predictable data flow, especially in larger and more complex applications.



Setting up Vuex



First, we need to install Vuex:


npm install vuex


Next, create a new file called store.js in the 'src' folder:


import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    tasks: [],
  },
  mutations: {
    addTask(state, task) {
      state.tasks.push(task);
    },
    updateTask(state, { index, task }) {
      state.tasks[index] = task;
    },
    deleteTask(state, index) {
      state.tasks.splice(index, 1);
    },
  },
});

export default store;


This code creates a Vuex store with the following components:

  • state: Defines the initial state of the application. Here, we have a tasks array to store our tasks.
    • mutations: Functions that modify the state. They are the only way to change the state of the store. We have mutations for adding, updating, and deleting tasks.

      Connecting to the Components

      Now, we need to connect the store to our components. Open main.js and import the store:

import Vue from 'vue';
import App from './App.vue';
import store from './store';

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  store,
  render: h =&gt; h(App),
});


Next, modify our components to use the store. In TodoList.vue:


  <template>
   <div class="container">
    <h1>
     To-Do List
    </h1>
    <input @keyup.enter="addTask" placeholder="Add new task..." type="text" v-model="newTask"/>
    <ul class="todo-list">
     <todoitem :key="index" :task="task" @delete-task="deleteTask" @update-task="updateTask" v-for="(task, index) in tasks">
     </todoitem>
    </ul>
   </div>
  </template>
  <script>
   import TodoItem from './TodoItem.vue';

export default {
  name: 'TodoList',
  components: {
    TodoItem,
  },
  computed: {
    tasks() {
      return this.$store.state.tasks;
    },
  },
  methods: {
    addTask() {
      if (this.newTask.trim() !== '') {
        this.$store.commit('addTask', {
          text: this.newTask,
          completed: false,
        });
        this.newTask = '';
      }
    },
    updateTask(task, index) {
      this.$store.commit('updateTask', { index, task });
    },
    deleteTask(index) {
      this.$store.commit('deleteTask', index);
    },
  },
};
  </script>


In TodoItem.vue, we don't need to make any changes because we're not directly manipulating the data anymore. The TodoList component is now responsible for handling interactions with the store.



The key changes here are:

  • computed property tasks: This property accesses the tasks array from the store's state.
    • this.$store.commit: We use this to call the store's mutations. When adding a new task, updating a task, or deleting a task, we commit the corresponding mutation to the store.

      Conclusion

      Building a To-Do App is a great way to learn and practice Vue.js principles. We've covered the basics of component structure, data binding, and event handling. We also introduced Vuex for centralized state management, which is essential for larger applications.

      Here are some key takeaways:

      • Component-based Architecture: Break down your application into reusable components for better organization and maintainability.
      • Data Binding and Events: Use v-model, v-for, v-bind, and v-on directives to create dynamic user interfaces and interact with data.
      • Vuex for State Management: Utilize Vuex to centralize your application's data, ensuring consistent and predictable data flow.

      Remember, this is just a starting point. You can further enhance this To-Do App by adding features like:

      • Persistence: Save tasks using LocalStorage or a server-side database.
      • Filters: Allow users to filter tasks based on completion status or other criteria.
      • Sorting: Implement sorting capabilities for the task list.
      • User Authentication: Add user accounts to personalize the app.

      With Vue.js, the possibilities are endless. As you continue exploring, you'll discover more powerful features and techniques to create complex and engaging web applications.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player