Vue JS Composition API 1 — Questions and Answers
Question 1: What does the `ref` function do in Vue 3 Composition API?
- Creates a reactive reference to a value, accessed via .value (Correct answer)
- Creates a DOM reference
- Registers a component reference
- Binds a template variable
Correct answer: Creates a reactive reference to a value, accessed via .value
`ref` wraps any value (primitive or object) in a reactive container accessible via `.value`, enabling Vue to track changes and update the DOM.
`ref(initialValue)` creates a reactive object with a single `.value` property. When `.value` is read, Vue tracks it as a reactive dependency. When `.value` is written, Vue triggers updates. In templates, Vue automatically unwraps refs so you don't need `.value` — `{{ count }}` works instead of `{{ count.value }}`. `ref` can hold any type including objects, but for objects you often prefer `reactive` for a more natural access pattern. Use `ref` for primitives and for values that need to be replaced entirely.
Question 2: What is the difference between `ref` and `reactive` in Vue 3?
- `ref` works with any value and uses .value; `reactive` creates a deep reactive proxy of an object (Correct answer)
- `ref` is for templates only; `reactive` is for scripts
- `reactive` requires a type annotation; `ref` does not
- `ref` is deprecated in Vue 3.4+
Correct answer: `ref` works with any value and uses .value; `reactive` creates a deep reactive proxy of an object
`ref` wraps any value in a single-property object (.value), while `reactive` creates a Proxy that makes all properties of an object deeply reactive without .value.
`ref(0)` produces `{ value: 0 }` — a reactive wrapper. `reactive({ count: 0 })` returns a Proxy where every property is reactive. Key differences: `reactive` cannot hold primitives (numbers, strings, booleans); it must be an object/array. `reactive` loses reactivity if destructured or reassigned (the original proxy is abandoned). `ref` can always be passed around and still work because the reactive container itself is the ref object. Vue 3.3+ added `toRef` and `toValue` helpers to bridge the two.
Question 3: How do you watch a reactive value for changes in Vue 3 Composition API?
- watch(count, (newVal, oldVal) => { ... }) (Correct answer)
- this.$watch('count', callback)
- computed(() => count.value)
- onMounted(() => { trackCount(count) })
Correct answer: watch(count, (newVal, oldVal) => { ... })
The `watch` function from Vue 3 Composition API observes a reactive source (ref, computed, getter function, or reactive object) and calls the callback when it changes.
`watch(source, callback, options)` is the Composition API equivalent of the Options API `watch` option. The source can be a ref, computed, a reactive object, or a getter function: `watch(() => obj.count, cb)`. The callback receives `(newValue, oldValue)`. Options include `immediate: true` (run immediately), `deep: true` (watch nested changes), and `flush: 'post'` (run after DOM updates). For multiple sources: `watch([refA, refB], ([a, b]) => { ... })`. Use `watchEffect` when you don't need old/new values.
Question 4: What is `watchEffect` and how does it differ from `watch`?
- `watchEffect` automatically tracks its reactive dependencies and re-runs; `watch` requires explicit source declaration (Correct answer)
- `watchEffect` is synchronous; `watch` is asynchronous
- `watch` is for templates; `watchEffect` is for scripts
- `watchEffect` only works with computed values
Correct answer: `watchEffect` automatically tracks its reactive dependencies and re-runs; `watch` requires explicit source declaration
`watchEffect` runs the callback immediately and automatically tracks any reactive values accessed inside it, re-running when they change. `watch` requires explicit sources.
`watchEffect(() => { console.log(count.value) })` runs immediately and re-runs whenever `count.value` changes — it figures out dependencies automatically. `watch(count, cb)` requires you to name the source explicitly but gives you old and new values and doesn't run immediately (unless `immediate: true`). Use `watchEffect` for simple side effects that depend on multiple reactive sources without caring about old values. Use `watch` when you need precise control, old/new value comparison, or lazy initialization.
Question 5: What does `computed` return in Vue 3 Composition API?
- A read-only ref whose value is lazily evaluated and cached until its dependencies change (Correct answer)
- A function that must be called to get the value
- A reactive object with multiple properties
- A Promise resolving to the computed value
Correct answer: A read-only ref whose value is lazily evaluated and cached until its dependencies change
`computed` returns a read-only ref. The getter runs lazily and caches the result, only re-evaluating when reactive dependencies change.
`const double = computed(() => count.value * 2)` returns a ComputedRef. Accessing `double.value` returns the cached computed value. Vue only re-runs the getter when a tracked reactive dependency changes. This is more efficient than methods (which recompute on every render) and watchEffect (which runs as a side effect). You can also create writable computed refs: `computed({ get: () => ..., set: (val) => { ... } })`. In templates, Vue automatically unwraps computed refs just like regular refs.
Question 6: What is `provide` and `inject` used for in Vue 3?
- To pass data from ancestor to descendant components without prop drilling (Correct answer)
- To share state between sibling components
- To inject external services into components
- To provide CSS styles to child components
Correct answer: To pass data from ancestor to descendant components without prop drilling
`provide` makes a value available to all descendant components in the tree, and `inject` retrieves that value, bypassing prop drilling through intermediate components.
Vue's provide/inject is a dependency injection system. A parent component calls `provide('key', value)` to make data available. Any descendant (grandchild, great-grandchild, etc.) can call `inject('key')` to receive it without needing props to be threaded through all intermediate components. You can provide reactive refs to keep injected values reactive. To prevent accidental mutations, use `readonly()` on the provided ref. Symbol keys are recommended for large apps to avoid name collisions. This pattern is widely used by component libraries like Vuetify.
What does the `ref` function do in Vue 3 Composition API?