We use cookies to enhance your experience on the site
CodeWorlds

watchEffect - Automatic Tracking

watchEffect automatically tracks all reactive dependencies used inside it.

Basics of watchEffect

1<script setup>
2import { ref, watchEffect } from 'vue'
3
4const count = ref(0)
5const message = ref('Hello')
6
7// Automatically tracks count and message
8watchEffect(() => {
9  console.log(`Count: ${count.value}, Message: ${message.value}`)
10})
11
12// Will be called:
13// 1. Immediately on initialization
14// 2. When count changes
15// 3. When message changes
16</script>

watch vs watchEffect

1import { ref, watch, watchEffect } from 'vue'
2
3const count = ref(0)
4
5// watch - explicit source, access to oldValue
6watch(count, (newVal, oldVal) => {
7  console.log(`${oldVal}${newVal}`)
8})
9
10// watchEffect - automatic tracking, no oldValue
11watchEffect(() => {
12  console.log(`Count: ${count.value}`)
13})

| Feature | watch | watchEffect | |-------|-------|-------------| | Source | Explicit | Automatic | | oldValue | Yes | No | | immediate | Optional | Always | | Lazy | Yes | No |

Cleanup in watchEffect

1<script setup>
2import { ref, watchEffect } from 'vue'
3
4const id = ref(1)
5
6watchEffect((onCleanup) => {
7  const controller = new AbortController()
8
9  fetch(`/api/artwork/${id.value}`, {
10    signal: controller.signal
11  })
12    .then(res => res.json())
13    .then(data => console.log(data))
14
15  // Cleanup - called before each re-run
16  onCleanup(() => {
17    controller.abort()
18  })
19})
20</script>

watchPostEffect and watchSyncEffect

1import { watchEffect, watchPostEffect, watchSyncEffect } from 'vue'
2
3// Default - before DOM update
4watchEffect(() => { /* ... */ })
5
6// After DOM update
7watchPostEffect(() => {
8  // DOM is already updated here
9})
10
11// Synchronously - immediately on change
12watchSyncEffect(() => {
13  // Warning: may affect performance
14})
Go to CodeWorlds