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:
- Create a Pinia Store: Define a Pinia store named
useTodoStorethat will hold the application's to-do list. - State: The store should contain a state property named
todos, which will be an array of objects. Each object should have at least anid(number) and atext(string) property. - Getters: Implement a getter named
completedTodosthat returns an array of to-do objects that are marked as completed (you'll need to add acompletedboolean property to your to-do objects). - Actions:
- Implement an action named
addTodothat accepts atextstring and adds a new to-do item to thetodosarray. Each new to-do should have a uniqueidand acompletedstatus offalse. - Implement an action named
toggleTodoCompletionthat accepts atodoId(number) and toggles thecompletedstatus of the corresponding to-do item. - Implement an action named
removeTodothat accepts atodoId(number) and removes the corresponding to-do item from thetodosarray.
- Implement an action named
- Component Integration:
- Create a
TodoList.vuecomponent 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.vuecomponent with an input field and a button to add new to-dos to the global state. - Ensure that changes made in
AddTodoForm.vueare reflected inTodoList.vueand vice-versa, demonstrating the global nature of the state.
- Create a
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
AddTodoFormand click "Add" to add a new to-do. - The
TodoListwill update automatically to show the new to-do. - Clicking on a to-do item in
TodoListshould visually indicate its completion status (e.g., by striking through the text) and update thecompletedstate. - Clicking a "Remove" button next to a to-do should remove it from the list.
- The
completedTodosgetter should accurately filter and return only the completed to-dos.
Examples
Example 1: Adding a To-Do
Input (User Action):
- User types "Buy groceries" into the
AddTodoForminput. - 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):
- In
TodoList.vue, the user clicks on the to-do item "Buy groceries" (which hasid: 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):
- In
TodoList.vue, the user clicks the "Remove" button next to the to-do item "Walk the dog" (which hasid: 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
idfor new to-dos should be a simple incrementing number, starting from 1. - The
textfor to-dos will be strings. - The
completedstatus 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.