Vue 3 Reactivity Transform di 2026: $ref, $computed dan Pertanyaan Interview
Panduan mendalam tentang Reactivity Transform Vue 3 meliputi $ref, $computed, dan pertanyaan interview yang sering diajukan untuk developer Vue senior.

Reactivity Transform merupakan fitur eksperimental Vue 3 yang bertujuan menyederhanakan penggunaan reactive state dengan menghilangkan kebutuhan .value pada ref. Meskipun fitur ini telah dihapus dari Vue core sejak versi 3.4, pemahaman tentang konsep dan alternatifnya tetap relevan dalam interview Vue developer karena menunjukkan kedalaman pengetahuan tentang sistem reaktivitas Vue.
Reactivity Transform ($ref, $computed) telah dihapus dari Vue 3.4 ke atas. Vue Macros menyediakan implementasi komunitas bagi tim yang masih membutuhkannya. Pemahaman konsep ini tetap bernilai untuk interview karena menunjukkan pengetahuan tentang evolusi Vue.
Memahami Masalah yang Dipecahkan Reactivity Transform
Sistem reaktivitas Vue 3 berbasis pada objek ref dan reactive. Ketika menggunakan ref, developer harus mengakses nilai melalui properti .value di dalam script, sementara di template akses langsung tanpa .value dimungkinkan karena unwrapping otomatis.
import { ref, computed } from 'vue'
// Pendekatan standar dengan .value
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
console.log(doubled.value)
}Reactivity Transform menghilangkan boilerplate .value dengan macro compiler yang mentransformasi kode pada waktu build.
// Dengan Reactivity Transform (deprecated)
let count = $ref(0)
const doubled = $computed(() => count * 2)
function increment() {
count++
console.log(doubled)
}Cara Kerja $ref dan $computed
Macro $ref mendeklarasikan variabel reaktif yang dapat digunakan seperti variabel JavaScript biasa. Compiler Vue mentransformasi kode ini menjadi penggunaan ref standar dengan .value yang tepat.
// Kode sumber dengan $ref
let username = $ref('')
let isValid = $computed(() => username.length >= 3)
function updateUsername(value: string) {
username = value
}
// Hasil transformasi compiler
import { ref, computed } from 'vue'
const username = ref('')
const isValid = computed(() => username.value.length >= 3)
function updateUsername(value: string) {
username.value = value
}Macro $$ untuk Escape Ref
Macro $$ memungkinkan mengakses objek ref yang mendasari ketika diperlukan, misalnya saat passing ref ke composable atau watch.
import { watch } from 'vue'
let count = $ref(0)
// Menggunakan $$ untuk mendapatkan ref object
watch($$(count), (newVal, oldVal) => {
console.log(`Count berubah dari ${oldVal} ke ${newVal}`)
})
// Passing ref ke composable
function useDoubled(countRef: Ref<number>) {
return computed(() => countRef.value * 2)
}
const doubled = useDoubled($$(count))Reactive Props Destructure
Vue 3.5 memperkenalkan destructuring props reaktif sebagai fitur stabil, menggantikan sebagian fungsionalitas Reactivity Transform untuk props.
<script setup lang="ts">
// Vue 3.5+ reactive props destructure
const { count = 0, title } = defineProps<{
count?: number
title: string
}>()
// count dan title tetap reaktif
const doubled = computed(() => count * 2)
</script>
<template>
<h1>{{ title }}</h1>
<p>Count: {{ count }}, Doubled: {{ doubled }}</p>
</template>Sebelum Vue 3.5, destructuring props memutus reaktivitas dan memerlukan toRefs:
const props = defineProps<{ count: number }>()
const { count } = toRefs(props) // Diperlukan untuk menjaga reaktivitasImplementasi Alternatif dengan Vue Macros
Vue Macros adalah koleksi macro yang dikelola komunitas, menyediakan fungsionalitas Reactivity Transform dan fitur tambahan lainnya.
import Vue from '@vitejs/plugin-vue'
import VueMacros from 'unplugin-vue-macros/vite'
export default defineConfig({
plugins: [
VueMacros({
plugins: {
vue: Vue(),
},
}),
],
})<script setup lang="ts">
// Dengan Vue Macros
let count = $ref(0)
let items = $ref<string[]>([])
const total = $computed(() => items.length)
const isEmpty = $computed(() => total === 0)
function addItem(item: string) {
items = [...items, item]
count++
}
</script>Pattern Modern Tanpa Reactivity Transform
Pendekatan yang direkomendasikan di Vue 3.5 menggunakan fitur built-in tanpa memerlukan macro eksternal.
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
// Konvensi penamaan: gunakan suffix Ref untuk kejelasan
const countRef = ref(0)
const itemsRef = ref<string[]>([])
// Computed properties
const total = computed(() => itemsRef.value.length)
const isEmpty = computed(() => total.value === 0)
// Composable dengan reactive state
function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => count.value++
const decrement = () => count.value--
const reset = () => count.value = initialValue
return {
count,
increment,
decrement,
reset
}
}
const { count, increment, decrement } = useCounter(10)
</script>Perbandingan ref vs reactive
Pemahaman kapan menggunakan ref versus reactive sering muncul dalam interview Vue.
import { ref, reactive, toRefs } from 'vue'
// ref: untuk primitive values dan single values
const count = ref(0)
const name = ref('Vue')
const isLoading = ref(false)
// reactive: untuk objects dengan multiple properties
const state = reactive({
user: null as User | null,
posts: [] as Post[],
pagination: {
page: 1,
perPage: 10
}
})
// Destructure reactive object dengan toRefs
const { user, posts } = toRefs(state)
// Keunggulan ref:
// 1. Dapat di-reassign sepenuhnya
// 2. Dapat di-pass ke functions tanpa kehilangan reaktivitas
// 3. Lebih predictable dengan TypeScript
// Keunggulan reactive:
// 1. Tidak perlu .value untuk nested access
// 2. Lebih natural untuk complex state objects
// 3. Automatic unwrapping di templateAdvanced Reactivity Patterns
Pattern-pattern lanjutan yang sering ditanyakan dalam interview senior Vue developer.
Custom Ref dengan Validasi
import { customRef } from 'vue'
function useDebouncedRef<T>(value: T, delay = 300) {
let timeout: ReturnType<typeof setTimeout>
return customRef<T>((track, trigger) => ({
get() {
track()
return value
},
set(newValue: T) {
clearTimeout(timeout)
timeout = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}))
}
// Penggunaan
const searchQuery = useDebouncedRef('', 500)Shallow Reactivity untuk Performa
import { shallowRef, shallowReactive, triggerRef } from 'vue'
// shallowRef: hanya level pertama yang reaktif
const largeList = shallowRef<Item[]>([])
function updateList(items: Item[]) {
largeList.value = items // Triggers update
}
function mutateItem(index: number) {
largeList.value[index].name = 'Updated'
triggerRef(largeList) // Manual trigger diperlukan
}
// shallowReactive: hanya properties level pertama yang reaktif
const config = shallowReactive({
theme: 'dark',
settings: { /* nested tidak reaktif */ }
})Siap menguasai wawancara Vue.js / Nuxt.js Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Pertanyaan Interview Vue Reactivity
Pertanyaan 1: Jelaskan perbedaan antara ref dan reactive
Jawaban yang diharapkan: ref membungkus nilai apapun (primitive atau object) dalam objek dengan properti .value, sedangkan reactive membuat proxy reaktif dari object. ref lebih fleksibel karena dapat menampung primitive dan dapat di-reassign sepenuhnya. reactive lebih ergonomis untuk complex nested objects tapi tidak dapat di-reassign dan kehilangan reaktivitas jika di-destructure tanpa toRefs.
Pertanyaan 2: Mengapa Reactivity Transform dihapus dari Vue core?
Jawaban yang diharapkan: Tim Vue memutuskan menghapus Reactivity Transform karena beberapa alasan: menambah kompleksitas mental dengan mencampur dua model reaktivitas, memerlukan tooling khusus yang tidak selalu tersedia, dan membuat debugging lebih sulit karena kode yang ditulis berbeda dengan kode yang dijalankan. Fitur reactive props destructure di Vue 3.5 mengatasi use case paling umum tanpa memerlukan macro global.
Pertanyaan 3: Bagaimana cara mempertahankan reaktivitas saat destructuring?
// Pertanyaan: Fix kode ini agar reaktif
const state = reactive({ count: 0, name: 'Vue' })
const { count, name } = state // Tidak reaktif!
// Jawaban:
import { toRefs } from 'vue'
const state = reactive({ count: 0, name: 'Vue' })
const { count, name } = toRefs(state) // Sekarang reaktif
// Atau gunakan computed untuk derived values
const count = computed(() => state.count)Pertanyaan 4: Kapan menggunakan shallowRef vs ref?
Jawaban yang diharapkan: Gunakan shallowRef ketika bekerja dengan large objects atau arrays yang sering di-replace secara keseluruhan tetapi jarang dimutasi secara internal. Ini menghindari overhead dari deep reactivity tracking. Contoh use case: response API besar, large datasets untuk tabel, atau state yang di-manage oleh external library.
Pertanyaan 5: Implementasikan computed writable
import { ref, computed } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(value: string) {
const parts = value.split(' ')
firstName.value = parts[0] || ''
lastName.value = parts.slice(1).join(' ') || ''
}
})
// Penggunaan
fullName.value = 'Jane Smith' // firstName = 'Jane', lastName = 'Smith'Best Practices Reaktivitas Vue 3
-
Preferensi ref untuk composables: Kembalikan
refdari composables karena lebih mudah di-destructure dan tetap reaktif. -
Gunakan readonly untuk data yang tidak boleh dimutasi:
readonly(state)mencegah mutasi tidak disengaja. -
Hindari deep reactivity yang tidak perlu: Gunakan
shallowRefataumarkRawuntuk data yang tidak perlu reaktif. -
Konsisten dengan konvensi penamaan: Tambahkan suffix seperti
RefatauStateuntuk kejelasan. -
Leverage TypeScript: Definisikan types untuk ref generics untuk mencegah runtime errors.
Kesimpulan
Meskipun Reactivity Transform telah dihapus dari Vue core, memahami konsep di baliknya memberikan insight berharga tentang sistem reaktivitas Vue. Fitur-fitur modern seperti reactive props destructure di Vue 3.5 menyediakan ergonomi yang lebih baik tanpa kompleksitas tambahan dari macro compiler. Dalam interview, kemampuan menjelaskan trade-off dari berbagai pendekatan reaktivitas menunjukkan pemahaman mendalam tentang Vue internals.
Bisakah kamu menemukan bug di Vue.js / Nuxt.js?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 9 September 2026
Tag
Bagikan
Artikel terkait

Vue 3 Composition API: Panduan Lengkap Menguasai Reaktivitas
Kuasai Vue 3 Composition API melalui panduan praktis ini. Pelajari ref, reactive, computed, watch, dan composables untuk membangun aplikasi Vue yang berkinerja tinggi.

Vue 3 Composables Tingkat Lanjut: Pola yang Dapat Digunakan Ulang dan Pertanyaan Interview 2026
Panduan lengkap Vue 3 composables tingkat lanjut: pola yang dapat digunakan ulang, penanganan asinkron, dependency injection, validasi form, pengujian terisolasi, dan pertanyaan interview teknis 2026.

Vue 3 Script Setup dan defineModel di 2026: Sintaks Modern dan Pertanyaan Interview
Panduan lengkap tentang sintaks script setup Vue 3, defineModel untuk two-way binding, reactive props destructure di Vue 3.5, dan pertanyaan interview yang sering diajukan.