Day 02 Components

Components, Props, and Events

Single-file components, prop validation, emits, provide/inject, and the component design patterns that keep a Vue application maintainable as it grows.

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

Single-file components, prop validation, emits, provide/inject, and the component design patterns that keep a Vue application maintainable as it grows.

01

How Vue's Reactivity Works

Vue tracks which reactive variables your template uses. When any of them change, Vue re-renders just the parts of the DOM that depend on that data. You don't call setState() or manually trigger updates — Vue handles it automatically.

There are two ways to create reactive state: ref() and reactive(). They behave differently and are suited to different situations.

02

ref vs reactive: When to Use Each

Use ref() for single values — strings, numbers, booleans, or even objects when you want to replace the whole thing. Use reactive() for objects and arrays when you'll only ever mutate their properties, never replace the whole object.

Vue Script
import { ref, reactive } from 'vue'

// ref: good for primitives and single values
const count = ref(0)
const username = ref('alice')
const isLoggedIn = ref(false)

// Access with .value in 

04

watch and watchEffect: Side Effects

Sometimes you need to run code in response to data changes — like calling an API when a search term updates, or saving to localStorage when a setting changes. That's what watch and watchEffect are for.

Vue Script
import { ref, watch, watchEffect } from 'vue'

const searchQuery = ref('')
const results = ref([])

// watch: explicit source, fires when source changes
// Gets old and new values
watch(searchQuery, async (newVal, oldVal) => {
  if (newVal.length > 2) {
    results.value = await fetchResults(newVal)
  }
})

// watch with options
watch(searchQuery, handler, {
  immediate: true,  // run once on mount
  deep: true        // watch nested object changes
})

// watchEffect: auto-tracks dependencies
// Runs immediately and whenever any reactive value it reads changes
watchEffect(() => {
  console.log('Search changed to:', searchQuery.value)
  // Vue automatically knows this depends on searchQuery
})

// Cleanup: stop watching when component unmounts
const stop = watchEffect(() => { /* ... */ })
// stop() when you're done
ℹ️
Use computed for derived values (things you display). Use watch for side effects (API calls, saving data, triggering animations). If you find yourself computing a value inside a watch, that's a signal to use computed instead.
📝 Day 2 Exercise
Build a Live Search Component
  1. Create a component with a text input bound to a ref search query.
  2. Add a hardcoded array of 20+ items (names, products, whatever you like).
  3. Use computed to filter the array based on the search query.
  4. Display the filtered results count with another computed property.
  5. Use watch to log every search query change to the console with a debounce of 300ms.
  6. Add a computed property for whether there are zero results, and show a 'No results found' message in that case.

Day 2 Summary

What's Next

The foundations from today carry directly into Day 3. In the next session the focus shifts to Vue Router and Navigation Guards — building directly on everything covered here.

Day 2 Checkpoint

Before moving on, verify you can answer these without looking:

  • What is the core concept introduced in this lesson, and why does it matter?
  • What are the two or three most common mistakes practitioners make with this topic?
  • Can you explain the key code pattern from this lesson to a colleague in plain language?
  • What would break first if you skipped the safeguards or best practices described here?
  • How does today's topic connect to what comes in Day 3?

Live Bootcamp

Learn this in person — 2 days, 5 cities

Thu–Fri sessions in Denver, Los Angeles, New York, Chicago, and Dallas. $1,490 per seat. June–October 2026.

Reserve Your Seat →
Continue To Day 3
Day 3: Pinia State Management