DEV Community

Olayemi Elsie
Olayemi Elsie

Posted on

Problem-Solving

Developing a Task Manager application using Vue 3 focused on:

  • Component composition
  • Props and events
  • State management
  • Composables
  • Clean structure and separation of concerns to organize the app logically, prevent mistakes, and make it easier to solve problems as they come up.

What the Task Manager App Does

The Task Manager is designed to help users organize their personal tasks. It allows users to:

  1. Add tasks – Quickly write down what needs to be done.

  2. Mark tasks as completed – Keep track of finished tasks.

  3. Delete tasks – Remove tasks that are no longer needed.

  4. Toggle all tasks – Mark all tasks as completed or uncompleted at once using Check All / Uncheck All.

  5. Delete all tasks – Clear all tasks in one click.

  6. Switch between dark and light mode – Change the app’s theme for comfortable viewing.

To get all these features working correctly, I needed careful planning before execution, which is the essence of problem-solving.

I realized that some parts were not planned well, which caused small bugs and edge-case issues, such as:

  • Long task texts breaking out of the container
  • Check All / Delete All buttons were not factored at the planning phase
  • Completed tasks missing the overline
  • Empty state was not factored at the planning phase

PLANNING PHASE
Before writing code, I thought of the following:

  • How should the layout look? What colors and interactions should I use?
  • Where should the task state live?
  • How will components communicate?
  • Should I use local state or a shared composable?
  • How do I prevent the app from becoming messy?

Breaking Down the Problem
Instead of building one big component, I split the app into smaller parts:

  • TaskManager (parent)
  • CardView
  • ListView
  • CheckAllBtns
  • EmptyState
  • useTasks (composable)

This made the app easier to understand and maintain, even though I didn’t plan all the UI edge cases at first.

KEY DESIGN DECISIONS

  1. Why Use a Composable for State Management?
  2. Problem: Multiple components needed access to the same task data.
  3. Options considered: Keep tasks in each component (local state) OR use a composable (shared state).
  4. Decision: I used a composable (useTasks) to store tasks and related functions.
  5. Reason: Keeps all task logic in one place and ensures a single source of truth. Example:

// useTasks.js
import { ref } from "vue";
const tasks = ref([]);
export function useTasks() {
const addTask = (text) => {
tasks.value.push({ text, completed: false });
};
return { tasks, addTask };
}

  1. Why Separate Components Instead of One Big File?
  2. Problem: The app was growing and harder to manage in one file.
  3. Decision: I separated the UI into smaller components.
  4. Reason: Easier to read, reuse, maintain, and debug.

  5. Why Use Slots Instead of Props in EmptyState?

  6. Problem: I needed to display custom content when no tasks exist.

  7. Decision: I used a slot.

  8. Reason: Slots allow passing HTML/components, while props are only for data.

  9. Why Start with Static Components First?

  10. Problem: I wanted to use dynamic components immediately.

  11. Decision: Built static components first, then made them dynamic.

  12. Reason: Easier to debug step by step before introducing dynamic rendering.

CHALLENGES & SOLUTIONS

Challenge 1: ListView had its own tasks array

  • What went wrong: Created a local tasks array inside ListView, not using the composable.
  • Problem: Changes in one component didn’t reflect in others.
  • Fix: Removed local state, used the composable instead.
  • Lesson learned: Always maintain a single source of truth.

Challenge 2: deleteAllTasks was in the wrong place

  • What went wrong: Placed deleteAllTasks inside a child component.
  • Problem: Children shouldn’t manage global state.
  • Fix: Moved logic into the composable and triggered it via events.
  • Lesson learned: Parent manages state; child emits events.

Challenge 3: Text overflow and missing underline

  • What went wrong: Long tasks broke the container; completed tasks didn’t show underline.
  • Fix: Added truncation for long text and proper styling for completed tasks.
  • Lesson learned: Edge cases matter; UI details should be planned in advance.

Challenge 4: Understanding slots vs props

  • What went wrong: Tried passing empty state using props.
  • Fix: Learned slots are better for content, props for data.
  • Lesson learned: Correct communication methods keep components flexible.

It is important to include problem-solving in software development. Proper planning, breaking the app into smaller components, and managing state thoughtfully made it easier to implement features and avoid mistakes. Even if some edge cases were not fully covered during planning, they can be detected and fixed more easily during execution.

Top comments (0)