Day 01 Foundations

Vue 3 Reactivity and the Composition API

ref, reactive, computed, and watch — Vue 3 reactivity from the inside out. The Composition API organizes complex component logic in a way the Options API cannot.

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

ref, reactive, computed, and watch — Vue 3 reactivity from the inside out. The Composition API organizes complex component logic in a way the Options API cannot.

01

Why Vue 3 and Not Vue 2?

Vue 2 is in maintenance mode — no new features, just security fixes until end of 2023 (already passed). Vue 3 with the Composition API is the current standard. If you're starting fresh, start with Vue 3. Everything in this course is Vue 3.

The Composition API replaced the Options API as the recommended way to write components. It's more flexible, easier to test, and makes code reuse straightforward. We'll use <script setup> syntax throughout — it's the cleanest way to write Vue components today.

02

Setting Up Your Project

Vite is the official build tool for Vue 3. It starts in under a second and hot-reloads instantly. Don't use Vue CLI for new projects — it's legacy.

Terminal
# Create a new Vue 3 project
npm create vite@latest my-app -- --template vue

cd my-app
npm install
npm run dev

Open http://localhost:5173. You'll see the Vite + Vue welcome page. Now open the project in your editor and look at the file structure:

Project Structure
my-app/
├── src/
│   ├── App.vue          ← root component
│   ├── main.js          ← app entry point
│   ├── components/      ← your components go here
│   └── assets/          ← images, css
├── index.html
└── vite.config.js
03

Your First Component

A Vue single-file component (SFC) has three sections: <script setup> for logic, <template> for HTML, and <style> for CSS. They all live in one .vue file.

src/components/Greeting.vue
<script setup>
import { ref } from 'vue'

// ref() creates a reactive variable
const name = ref('World')
const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <div class="greeting">
    <h1>Hello, {{ name }}!</h1>
    
    <!-- v-model creates two-way binding -->
    <input v-model="name" placeholder="Enter your name" />
    
    <p>Count: {{ count }}</p>
    <button @click="increment">Add One</button>
  </div>
</template>

<style scoped>
.greeting {
  padding: 24px;
  font-family: sans-serif;
}
button {
  margin-top: 8px;
  padding: 8px 16px;
  cursor: pointer;
}
</style>
💡
The .value thing: When you read or write a ref inside <script setup>, you use name.value. Inside the template, Vue automatically unwraps it — so you just write {{ name }}. This trips everyone up once. Now you know.
04

Template Syntax Essentials

Vue's template is HTML with special directives (attributes starting with v-). These are the ones you'll use every day:

Vue Template
<script setup>
import { ref } from 'vue'

const show = ref(true)
const items = ref(['Apples', 'Bananas', 'Cherries'])
const selectedColor = ref('blue')
</script>

<template>
  <!-- v-if / v-else: conditional rendering -->
  <p v-if="show">Visible</p>
  <p v-else>Hidden</p>
  
  <!-- v-for: list rendering -->
  <ul>
    <li v-for="item in items" :key="item">{{ item }}</li>
  </ul>
  
  <!-- :attr (v-bind shorthand): dynamic attribute -->
  <div :class="selectedColor">Colored box</div>
  
  <!-- @event (v-on shorthand): event listener -->
  <button @click="show = !show">Toggle</button>
  
  <!-- v-model: two-way binding on input -->
  <select v-model="selectedColor">
    <option value="blue">Blue</option>
    <option value="red">Red</option>
  </select>
</template>
05

Using Components Inside Components

Import a component and use it as an HTML tag. With <script setup>, imported components are automatically available in the template — no registration step needed.

src/App.vue
<script setup>
import Greeting from './components/Greeting.vue'
</script>

<template>
  <main>
    <Greeting />
  </main>
</template>

Pass data to child components with props, and communicate back up with emits:

Child Component (UserCard.vue)
<script setup>
// defineProps: declare what data the parent can pass in
const props = defineProps({
  username: String,
  score: {
    type: Number,
    default: 0
  }
})

// defineEmits: declare events this component can fire
const emit = defineEmits(['delete'])
</script>

<template>
  <div class="card">
    <h3>{{ username }}</h3>
    <p>Score: {{ score }}</p>
    <button @click="emit('delete', username)">Remove</button>
  </div>
</template>
Parent Component
<script setup>
import UserCard from './components/UserCard.vue'
import { ref } from 'vue'

const users = ref([
  { username: 'alice', score: 42 },
  { username: 'bob', score: 17 }
])

function removeUser(name) {
  users.value = users.value.filter(u => u.username !== name)
}
</script>

<template>
  <UserCard
    v-for="user in users"
    :key="user.username"
    :username="user.username"
    :score="user.score"
    @delete="removeUser"
  />
</template>
ℹ️
The pattern is: props down, events up. Parent sends data to children via props. Children communicate back to parents via emits. This one-way data flow prevents bugs that come from multiple components mutating the same data.
📝 Day 1 Exercise
Build a Task List App
  1. Create a new Vue project with npm create vite@latest.
  2. Build a TaskList.vue component with a ref array of tasks (strings).
  3. Add an input + button to add new tasks to the list.
  4. Render each task with v-for, with a delete button next to each one.
  5. Add a checkbox per task using v-model to toggle completed state. Cross out completed tasks with CSS.
  6. Import and use your component in App.vue.

Day 1 Summary

What's Next

The foundations from today carry directly into Day 2. In the next session the focus shifts to Components, Props, and Events — building directly on everything covered here.

Day 1 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 2?

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 2
Day 2: Reactivity — ref, reactive, computed, watchers