Hone logo
Hone
Problems

Vue 3 Global State Management with Pinia

This challenge focuses on implementing a robust global state management solution in a Vue 3 application using Pinia. You'll learn how to create, access, and modify shared data across different components, which is crucial for building complex and maintainable Vue applications.

Problem Description

Your task is to build a simple to-do list application where the list of to-dos is managed as global state. This global state should be accessible and modifiable from various components within the Vue application. You will use Pinia, the official state management library for Vue 3, to achieve this.

Requirements:

  1. Create a Pinia Store: Define a Pinia store named useTodoStore that will hold the application's to-do list.
  2. State: The store should contain a state property named todos, which will be an array of objects. Each object should have at least an id (number) and a text (string) property.
  3. Getters: Implement a getter named completedTodos that returns an array of to-do objects that are marked as completed (you'll need to add a completed boolean property to your to-do objects).
  4. Actions:
    • Implement an action named addTodo that accepts a text string and adds a new to-do item to the todos array. Each new to-do should have a unique id and a completed status of false.
    • Implement an action named toggleTodoCompletion that accepts a todoId (number) and toggles the completed status of the corresponding to-do item.
    • Implement an action named removeTodo that accepts a todoId (number) and removes the corresponding to-do item from the todos array.
  5. Component Integration:
    • Create a TodoList.vue component that displays all the to-dos. It should allow users to mark a to-do as completed (by clicking on it) and remove a to-do (e.g., via a button).
    • Create an AddTodoForm.vue component with an input field and a button to add new to-dos to the global state.
    • Ensure that changes made in AddTodoForm.vue are reflected in TodoList.vue and vice-versa, demonstrating the global nature of the state.

Expected Behavior:

  • When the application loads, an empty to-do list should be displayed (or a default list if you choose to initialize it).
  • Users can type text into the AddTodoForm and click "Add" to add a new to-do.
  • The TodoList will update automatically to show the new to-do.
  • Clicking on a to-do item in TodoList should visually indicate its completion status (e.g., by striking through the text) and update the completed state.
  • Clicking a "Remove" button next to a to-do should remove it from the list.
  • The completedTodos getter should accurately filter and return only the completed to-dos.

Examples

Example 1: Adding a To-Do

Input (User Action):

  1. User types "Buy groceries" into the AddTodoForm input.
  2. User clicks the "Add" button.

State Before: todos: []

State After: todos: [{ id: 1, text: "Buy groceries", completed: false }]

Explanation: The addTodo action is called with "Buy groceries". A new to-do object with a unique ID, the provided text, and completed: false is added to the todos array in the Pinia store.

Example 2: Toggling To-Do Completion

Input (User Action):

  1. In TodoList.vue, the user clicks on the to-do item "Buy groceries" (which has id: 1).

State Before: todos: [{ id: 1, text: "Buy groceries", completed: false }]

State After: todos: [{ id: 1, text: "Buy groceries", completed: true }]

Explanation: The toggleTodoCompletion action is called with todoId: 1. The completed property of the to-do object with id: 1 is flipped from false to true.

Example 3: Removing a To-Do

Input (User Action):

  1. In TodoList.vue, the user clicks the "Remove" button next to the to-do item "Walk the dog" (which has id: 2).

State Before: todos: [{ id: 1, text: "Buy groceries", completed: true }, { id: 2, text: "Walk the dog", completed: false }]

State After: todos: [{ id: 1, text: "Buy groceries", completed: true }]

Explanation: The removeTodo action is called with todoId: 2. The to-do object with id: 2 is removed from the todos array.

Constraints

  • You must use Vue 3 and Pinia.
  • The id for new to-dos should be a simple incrementing number, starting from 1.
  • The text for to-dos will be strings.
  • The completed status will be a boolean.
  • Your solution should be written in TypeScript.
  • No external UI libraries beyond Vue and Pinia are allowed for the core state management and component logic.

Notes

  • Consider how you will initialize the Pinia store. You can provide an initial state or leave it empty.
  • Think about how to generate unique IDs. A simple counter within the store will suffice.
  • Styling for visual feedback (like strikethrough for completed items) is encouraged but not the primary focus of the challenge.
  • This challenge is designed to test your understanding of Pinia's core concepts: state, getters, and actions, and how to integrate them into Vue components.
Loading editor...
typescript