Suggest an editImprove this articleRefine the answer for “What does watch() do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`watch()`** watches for changes in reactive values (created via `ref`, `reactive`, `computed`, etc.) and runs the given function only when those values actually change. **Key point:** you use it when you need to perform an action (for example, an API call), not just update the UI.Shown above the full answer for quick recall.Answer (EN)Image## 1. What `watch()` does `watch()` **watches for changes in reactive values** (created via `ref`, `reactive`, `computed`, etc.) and runs the given function **only when** those values actually change. ### Syntax: ```javascript watch(source, callback, options?) ``` - `source` - what we watch (`ref`, `reactive`, a function, or an array). - `callback(newValue, oldValue)` - called on change. - `options` - additional settings (`immediate`, `deep`, `flush`, etc). --- ## 2. The simplest example ```javascript import { ref, watch } from 'vue' const count = ref(0) watch(count, (newVal, oldVal) => { console.log(`count changed: ${oldVal} → ${newVal}`) }) count.value++ // triggers the callback ``` Here `watch()` "subscribes" to changes in `count.value`. When the value changes, the callback is called. --- ## 3. How it works internally Under the hood, `watch()` creates an **effect**, just like `computed`, but with "only on change" behavior. 1. Vue remembers which reactive data were used in the source function (`source`). 2. When that data changes, Vue calls the callback. 3. Vue compares the old and new value (a shallow comparison). 4. If the value changed, your logic runs. --- ## 4. Example with a `reactive` object ```javascript import { reactive, watch } from 'vue' const user = reactive({ name: 'Tim', age: 25 }) // Watch the whole object watch(user, (newUser, oldUser) => { console.log('user changed:', newUser) }) ``` But note: > When watching a `reactive` object, changes **inside** the object do not trigger the callback by default, > unless you specify `{ deep: true }`. Correct: ```javascript watch(user, (newVal, oldVal) => { console.log('user changed deeply:', newVal) }, { deep: true }) ``` --- ## 5. Watching a specific property Instead of the whole object, you can pass a function, a "selector". ```javascript watch( () => user.name, // watch only name (newName, oldName) => { console.log(`Name changed: ${oldName} → ${newName}`) } ) ``` This is the **preferred way** - it is performant and targeted. --- ## 6. `watch()` options | Option | Description | Example | |---|---|---| | `immediate: true` | Run the callback immediately on initialization (with the current value) | `watch(count, cb, { immediate: true })` | | `deep: true` | Watch all nested changes in an object/array | `watch(user, cb, { deep: true })` | | `flush` | Determines **when the watcher runs** relative to the render. | `watch(value, cb, { flush: 'post' })` | | `onCleanup(fn)` | Lets you clean up a side effect before the next call | see below | --- ## 7. Cleaning up side effects Often, `watch()` needs to clean up timers, subscriptions, and so on. Vue passes an `onCleanup` function into the callback so you can clean up the previous effect: ```javascript watch(searchQuery, (newQuery, oldQuery, onCleanup) => { const controller = new AbortController() fetch(`/api?q=${newQuery}`, { signal: controller.signal }) // cancel the previous request if the value changed again onCleanup(() => controller.abort()) }) ``` --- ## 8. Watching several sources You can watch several values at once by passing an array: ```javascript const first = ref('Tim') const last = ref('Cook') watch([first, last], ([newFirst, newLast], [oldFirst, oldLast]) => { console.log(`Name: ${oldFirst} ${oldLast} → ${newFirst} ${newLast}`) }) ``` Vue tracks all the dependencies, and the callback is called if at least one of them changes. --- ## 9. Difference between `watch()` and `watchEffect()` | Criterion | `watch()` | `watchEffect()` | |---|---|---| | What it tracks | Specific reactive values or functions | Everything used inside the effect | | When it runs | Only when values change | Immediately on start and on every change | | Has `oldValue` | Yes | No | | Fine-grained control | Yes (you can specify `deep`, `immediate`) | No, everything is automatic | | Typical case | React to a state change | Run side effects on any change | Example: ```javascript // watch() watch(count, (newVal, oldVal) => console.log(newVal)) // watchEffect() watchEffect(() => { console.log(count.value) }) ``` --- ## 10. A practical example For example, you want to react to a change in the search string, but not on every render: ```javascript const query = ref('') watch(query, async (newQuery) => { results.value = await fetch(`/api?q=${newQuery}`).then(r => r.json()) }, { immediate: true }) ``` Here `immediate: true` gives the first request when the component mounts, and after that `watch()` only triggers when `query` changes. --- ## 11. Short and simple > `watch()` is a "reactive listener": > it tracks specific data and calls a function when it changes. **You use it when you need to perform an action, not just update the UI.** --- ## An example to remember | What you want | What to use | |---|---| | I want the UI to update itself when the data changes | `reactive()` / `ref()` / `computed()` | | I want to run a side effect when the data changes (e.g. an API call, a log, a timer, local storage) | `watch()` |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.