Reactivity: ref, reactive and computed
Harry
· 14 Sep 2026
· 1 views
Advertisement
ref for single values
In the Composition API, wrap a value in ref() to make it reactive. In the <script> you access it via .value; in the template Vue unwraps it for you:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++ // .value in script
}
</script>
<template>
<button @click="increment">{{ count }}</button> <!-- no .value here -->
</template>
reactive for objects
reactive() makes an entire object reactive, accessed without .value:
import { reactive } from 'vue'
const user = reactive({ name: 'Ada', age: 36 })
user.age++ // triggers updates
Rule of thumb: use ref for primitives and single values, reactive for objects – or just use ref everywhere for consistency.
computed: derived state
A computed value is derived from other reactive state and is cached – it only recalculates when its dependencies change:
import { ref, computed } from 'vue'
const price = ref(100)
const qty = ref(3)
const total = computed(() => price.value * qty.value) // 300, auto-updates
Prefer computed over putting complex expressions in the template – it is cleaner and cached.
Watching for changes
When you need to run a side effect on change (call an API, log), use watch:
import { watch } from 'vue'
watch(count, (newVal, oldVal) => console.log(newVal))
Key points
ref()makes single values reactive; use.valuein script, not in template.reactive()makes whole objects reactive.computed()derives cached values that update when dependencies change.watch()runs side effects in response to state changes.