Chapter 110: Vue Exercises

Vue-exercises, and let’s do what real teachers should do after theory:

Hands-on exercises — the only way you actually learn Vue.

I’m not going to give you 50 tiny “print hello world” tasks. Instead, I’m giving you 10 carefully sequenced, realistic exercises that build on each other, cover 90% of what real Vue developers do every week, and prepare you for medium-to-large real projects.

Each exercise has:

  • clear goal
  • starter code (or empty file if you want full challenge)
  • hints (but try without them first)
  • expected outcome / acceptance criteria
  • bonus / stretch goals (for when you finish early)

You should do them in order — they gradually increase difficulty and combine concepts.

Let’s start.

Exercise 1 – Basic Counter with Composition API + reactivity fundamentals

Goal: Build a simple counter that shows all basic reactivity patterns.

File: Counter.vue

vue

Requirements:

  1. Two buttons: +1 and Reset
  2. Show current count
  3. Show “Even” / “Odd” label that updates instantly
  4. Show “High score” that remembers the maximum value ever reached
  5. Disable +1 button when count ≥ 20 (show message “Limit reached”)
  6. Add a text input → show live “Double count would be: XX” below it (use .number modifier)

Acceptance criteria:

  • Count increases/decreases correctly
  • Even/Odd updates immediately
  • High score persists even after reset
  • Button disables at 20
  • Double preview works with number input

Hints (only look after 15 min struggle):

  • Use ref for count, highScore, inputValue
  • Use computed for isEven, doublePreview, isMaxReached
  • Use ternary in template for disable + message

Bonus:

  • Add –1 button (but never go below 0)
  • Add keyboard shortcut: press ArrowUp → +1, ArrowDown → –1

Exercise 2 – Todo List with TransitionGroup + emits + v-for + key

Goal: Build classic todo list — but with animations and clean separation (child emits, parent manages state)

Files:

  • TodoApp.vue (parent)
  • TodoItem.vue (child)

Requirements:

  1. Input + Add button (or Enter)
  2. List with checkbox + text + delete button
  3. Checkbox toggles done state → strikethrough + fade animation
  4. Delete item → leave animation (slide out)
  5. Show “X items left” counter
  6. Filter: All / Active / Completed buttons
  7. Clear Completed button

Acceptance criteria:

  • Add / toggle / delete works
  • Animations are smooth (use <TransitionGroup name=”list”>)
  • Filter updates instantly
  • Correct items-left count
  • :key is used correctly (use id, not index)

Bonus:

  • Add edit on double-click (input appears, save on Enter/Blur)
  • Persist todos in localStorage (use watch + onMounted)

Exercise 3 – Tabs with <KeepAlive> + onActivated / onDeactivated

Goal: Build tabbed interface where each tab preserves state (input value, scroll position)

Requirements:

  1. Three tabs: Overview, Notes, Settings
  2. Use <KeepAlive>
  3. Each tab has:
    • textarea (Notes tab)
    • long scrollable dummy content (Overview tab)
    • checkbox + number input (Settings tab)
  4. Switch tabs 10 times → verify:
    • textarea content preserved
    • scroll position preserved in Overview
    • checkbox & number value preserved in Settings

Acceptance criteria:

  • State survives tab switches
  • onActivated restores scroll
  • onDeactivated saves scroll
  • No re-mount flicker (use Devtools to confirm)

Bonus:

  • Add fade transition between tabs
  • Add “last visited” timestamp per tab (shown in header)

Exercise 4 – Form with multiple v-model + validation + error handling

Goal: Build signup form with real validation logic

Requirements:

  1. Fields: name, email, password, confirm password, age (number), country (select), interests (checkbox group)
  2. Live validation messages (red text below fields)
  3. Submit button disabled until form valid
  4. Show success message on submit (fake delay 1.5s)
  5. Use .trim, .number, .lazy where appropriate

Acceptance criteria:

  • Name ≥ 3 chars
  • Email has @
  • Password ≥ 8 chars, match confirm
  • Age ≥ 18
  • Country selected
  • At least 1 interest checked
  • Button disables correctly
  • Success message appears after submit

Bonus:

  • Add password strength indicator (weak/medium/strong)
  • Show/hide password toggle button

Exercise 5 – Modal system with Teleport + Transition + expose + slots

Goal: Build reusable modal with programmatic control

Requirements:

  1. <Modal> component with v-model support
  2. Expose open(), close() methods via defineExpose
  3. Named slots: header, default (body), footer
  4. Close on overlay click + Esc key
  5. Prevent background scroll when open
  6. Animation (fade + scale)

Acceptance criteria:

  • Open/close from parent via ref or v-model
  • Slots work (custom header/footer)
  • Esc closes modal
  • Body scroll disabled when open (use class on <body>)

Bonus:

  • Add confirm event
  • Add loading state (spinner in footer)

Exercise 6 – Error Boundary + Suspense + async component

Goal: Build crash-proof section with loading & error handling

Requirements:

  1. <ErrorBoundary> component using onErrorCaptured
  2. Wrap <Suspense> around lazy-loaded component
  3. Create dummy async component that sometimes throws error
  4. Show fallback UI on error + retry button

Acceptance criteria:

  • Error in child → fallback shown, app doesn’t crash
  • Slow-loading child → Suspense fallback shown
  • Retry button resets error state

Bonus:

  • Send error to console/Sentry-like service
  • Add loading spinner inside Suspense

Exercise 7 – Dashboard with KeepAlive + Transition + v-memo + performance

Goal: Build mini dashboard that shows performance patterns

Requirements:

  1. Tabs: Overview, Analytics, Settings
  2. Use <KeepAlive>
  3. Analytics tab has fake heavy chart (use v-memo to prevent re-render on tab switch)
  4. Add live clock (setInterval) → pause in onDeactivated
  5. Add scrollable news feed → restore scroll in onActivated

Acceptance criteria:

  • Tab switch is instant (KeepAlive)
  • Chart doesn’t re-render unnecessarily (v-memo)
  • Clock pauses when tab hidden
  • Scroll position restored when returning

Bonus:

  • Add onRenderTriggered temporarily → prove chart is not re-rendered on tab switch

Final Words – How to Approach These Exercises

  1. Create one new Vue project (Vite + Vue 3 + TypeScript)
  2. Make one component per exercise
  3. Commit after each one (git commit -m “Exercise 3: Tabs with KeepAlive”)
  4. Use Vue Devtools constantly — watch reactivity graph, timeline, component tree
  5. After finishing all 7 → try combining 3–4 of them into one mini-app (dashboard + modal + tabs + error boundary)

Any exercise confusing? Want starter code / solution hints / full repo link for any of them?

Just tell me which one — we’ll build it together live, line by line 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *