# Computed and watch
This section uses single-file component syntax for code examples
# computed
Takes a getter function and returns an immutable reactive ref object for the returned value from the getter.
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // error
2
3
4
5
6
Alternatively, it can take an object with get
and set
functions to create a writable ref object.
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
2
3
4
5
6
7
8
9
10
Typing:
// read-only
function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>>
// writable
function computed<T>(options: { get: () => T; set: (value: T) => void }): Ref<T>
2
3
4
5
# watchEffect
Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed.
const count = ref(0)
watchEffect(() => console.log(count.value))
// -> logs 0
setTimeout(() => {
count.value++
// -> logs 1
}, 100)
2
3
4
5
6
7
8
9
Typing:
function watchEffect(
effect: (onInvalidate: InvalidateCbRegistrator) => void,
options?: WatchEffectOptions
): StopHandle
interface WatchEffectOptions {
flush?: 'pre' | 'post' | 'sync' // default: 'pre'
onTrack?: (event: DebuggerEvent) => void
onTrigger?: (event: DebuggerEvent) => void
}
interface DebuggerEvent {
effect: ReactiveEffect
target: any
type: OperationTypes
key: string | symbol | undefined
}
type InvalidateCbRegistrator = (invalidate: () => void) => void
type StopHandle = () => void
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
See also: watchEffect
guide
# watch
The watch
API is the exact equivalent of the Options API this.$watch (and the corresponding watch option). watch
requires watching a specific data source and applies side effects in a separate callback function. It also is lazy by default - i.e. the callback is only called when the watched source has changed.
Compared to watchEffect,
watch
allows us to:- Perform the side effect lazily;
- Be more specific about what state should trigger the watcher to re-run;
- Access both the previous and current value of the watched state.
# Watching a Single Source
A watcher data source can either be a getter function that returns a value, or directly a ref:
// watching a getter
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
// directly watching a ref
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
2
3
4
5
6
7
8
9
10
11
12
13
14
# Watching Multiple Sources
A watcher can also watch multiple sources at the same time using an array:
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
/* ... */
})
2
3
# Shared Behavior with watchEffect
watch
shares behavior with watchEffect
in terms of manual stoppage, side effect invalidation (with onInvalidate
passed to the callback as the 3rd argument instead), flush timing and debugging.
Typing:
// watching single source
function watch<T>(
source: WatcherSource<T>,
callback: (
value: T,
oldValue: T,
onInvalidate: InvalidateCbRegistrator
) => void,
options?: WatchOptions
): StopHandle
// watching multiple sources
function watch<T extends WatcherSource<unknown>[]>(
sources: T
callback: (
values: MapSources<T>,
oldValues: MapSources<T>,
onInvalidate: InvalidateCbRegistrator
) => void,
options? : WatchOptions
): StopHandle
type WatcherSource<T> = Ref<T> | (() => T)
type MapSources<T> = {
[K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never
}
// see `watchEffect` typing for shared options
interface WatchOptions extends WatchEffectOptions {
immediate?: boolean // default: false
deep?: boolean
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
See also: watch
guide
← Refs Composition API →