🧩 1. What is setup()?
🧠 Concept:
The setup() function is the entry point for using the Composition API inside a Vue component.
It runs before the component is created — and is used to define:
- Reactive state (
ref,reactive) - Computed properties
- Methods
- Watchers
- Lifecycle hooks (
onMounted, etc.)
Whatever you return from setup() becomes available in your template.
✅ Example:
<template>
<h2>Hello, {{ name }}!</h2>
<button @click="changeName">Change Name</button>
</template>
<script setup>
import { ref } from 'vue'
// Define reactive state
const name = ref('Vue Learner')
// Define method
function changeName() {
name.value = 'Vue Master'
}
</script>
🧠 Explanation:
- Everything in
<script setup>automatically runs insidesetup(). - You don’t need to
returnvariables manually (Vue handles that automatically). - The
namevariable is reactive because it was created withref().
⚙️ 2. ref() — Reactive Primitive Values
🧠 Concept:
ref() creates a reactive reference to a value (string, number, boolean, etc.).
- It returns an object with a
.valueproperty. - When
.valuechanges, the DOM automatically updates.
✅ Example:
<template>
<p>Count: {{ count }}</p>
<button @click="count++">Increment</button>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
🧩 Explanation:
countis a reactive object:{ value: 0 }.- In JavaScript, you access it via
count.value. - In the template, Vue automatically unwraps
.value, so you can just write{{ count }}.
🧠 Example (Different Types)
const name = ref('Alice') // String
const age = ref(25) // Number
const isActive = ref(true) // Boolean
const items = ref(['A', 'B']) // Array
If you mutate arrays or objects inside a ref, Vue still tracks the changes:
items.value.push('C') // still reactive
🧱 3. reactive() — Reactive Objects
🧠 Concept:
reactive() makes an entire object reactive (deep reactivity).
Unlike ref, you don’t need .value.
✅ Example:
<template>
<p>{{ user.name }} ({{ user.age }} years old)</p>
<button @click="user.age++">Increase Age</button>
</template>
<script setup>
import { reactive } from 'vue'
const user = reactive({
name: 'Alice',
age: 25
})
</script>
🧠 Explanation:
- The whole
userobject is reactive. - You can directly mutate
user.age, and Vue will track it. - You don’t need
.value.
⚖️ ref() vs reactive()
| Feature | ref() | reactive() |
|---|---|---|
| Used for | Primitives (string, number, boolean) | Objects, arrays, nested data |
| Access | .value in JS, auto-unwrapped in template | Direct access (user.name) |
| Deep reactivity | ✅ For nested objects but less convenient | ✅ Automatic for all nested levels |
| Best for | Simple data, counters, toggles | Complex states, grouped data |
🧩 Example Comparison
// Using ref
const count = ref(0)
count.value++
// Using reactive
const state = reactive({ count: 0 })
state.count++
Both are reactive, but reactive() feels more natural when dealing with multiple fields.
🧠 4. Using ref and reactive Together
You can combine both for clean, modular code.
✅ Example:
<template>
<div>
<h3>{{ user.name }} — {{ age }}</h3>
<button @click="growOlder">Grow Older</button>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
const user = reactive({ name: 'Bob' })
const age = ref(20)
function growOlder() {
age.value++
}
</script>
💡 5. Inside Regular setup() (non-<script setup>)
If you’re using the traditional component syntax:
export default {
setup() {
const count = ref(0)
function increment() {
count.value++
}
return { count, increment }
}
}
🧠 Everything returned from setup() is available in your template.
⚡ Bonus: Reactive Caveats
❌ You can’t destructure a reactive object directly
This breaks reactivity:
const user = reactive({ name: 'Alice' })
const { name } = user // ❌ breaks reactivity
✅ Fix using toRefs():
import { toRefs } from 'vue'
const { name } = toRefs(user)
Now name remains reactive.
🧩 Summary
| Concept | Description | Example |
|---|---|---|
setup() | Main entry point for Composition API | setup() { ... } |
ref() | Creates a reactive reference (primitives) | const count = ref(0) |
reactive() | Makes an object deeply reactive | const user = reactive({ name: 'Bob' }) |
toRefs() | Keeps destructured properties reactive | const { name } = toRefs(user) |
