Your First Vue App
The best way to understand Vue’s reactive data model is to build something interactive. Start with the simplest possible example: a counter.
Clearing the scaffolded code
Section titled “Clearing the scaffolded code”Open src/App.vue. By default it has imports and components from the welcome page. Delete everything inside the file and replace it with:
<script setup lang="ts">import { ref } from 'vue'
const count = ref(0)
function increment() { count.value++}</script>
<template> <div> <p>Count: {{ count }}</p> <button @click="increment">+1</button> </div></template>Save the file. The browser shows a paragraph with “Count: 0” and a button. Click the button — the count increases.
What just happened
Section titled “What just happened”This small example contains the entire Vue reactive loop:
ref(0) creates a reactive reference wrapping the number 0. Any change to count.value automatically triggers a re-render of any template that uses count.
{{ count }} is Vue’s interpolation syntax. It renders the current value of count into the DOM. Inside a template, Vue automatically unwraps refs — you write {{ count }}, not {{ count.value }}.
@click="increment" is shorthand for v-on:click="increment". It attaches a click event listener that calls increment when the button is clicked.
increment() mutates count.value. Vue detects the change and updates the DOM.
This is the reactive loop: data changes → DOM updates automatically. No document.querySelector, no element.textContent = ....
Adding a decrement button
Section titled “Adding a decrement button”Extend the example:
<script setup lang="ts">import { ref } from 'vue'
const count = ref(0)</script>
<template> <div> <p>Count: {{ count }}</p> <button @click="count--">-1</button> <button @click="count++">+1</button> </div></template>Note that @click="count++" works directly — simple expressions can be written inline without a separate function.
TypeScript in the template
Section titled “TypeScript in the template”Because you used lang="ts" in the script block, TypeScript is active. Try changing ref(0) to ref('hello') and then doing count++ — TypeScript will report a type error because you can’t increment a string. This is the TypeScript integration working.
Exercise
Section titled “Exercise”- In your
my-first-vue-appproject, replacesrc/App.vuewith the counter example above. - Add a “Reset” button that sets
countback to0when clicked. - Add a paragraph that shows “Above zero” when
count > 0and “Zero or below” otherwise. (Hint: use a ternary inside{{ }}.) - Observe in the browser how the paragraph text changes as you increment and decrement.
ref(value)creates a reactive reference — changes to.valuetrigger re-renders.{{ expression }}interpolates a value into the template; refs are auto-unwrapped.@click="handler"is shorthand forv-on:click— it attaches an event listener.- Simple expressions can go inline in event handlers; complex logic goes in functions.