doWatch() — vue Function Reference
Architecture documentation for the doWatch() function in apiWatch.ts from the vue codebase.
Entity Profile
Dependency Diagram
graph TD 880ea200_f528_af26_3f6f_c77fc2f21647["doWatch()"] 27ac0da7_848d_2b52_5b63_5eb582827a0b["watchEffect()"] 27ac0da7_848d_2b52_5b63_5eb582827a0b -->|calls| 880ea200_f528_af26_3f6f_c77fc2f21647 cff31b8c_9131_2f34_6ed5_01a93ff663ec["watchPostEffect()"] cff31b8c_9131_2f34_6ed5_01a93ff663ec -->|calls| 880ea200_f528_af26_3f6f_c77fc2f21647 fdfac1cb_5889_15fa_76dd_977bb613a1f7["watchSyncEffect()"] fdfac1cb_5889_15fa_76dd_977bb613a1f7 -->|calls| 880ea200_f528_af26_3f6f_c77fc2f21647 de6a892d_79ff_ad64_7fc3_5f2fc0b51eb0["watch()"] de6a892d_79ff_ad64_7fc3_5f2fc0b51eb0 -->|calls| 880ea200_f528_af26_3f6f_c77fc2f21647 de6a892d_79ff_ad64_7fc3_5f2fc0b51eb0["watch()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| de6a892d_79ff_ad64_7fc3_5f2fc0b51eb0 b6fb2fe6_1e20_8aa7_252b_c7c3e62b0e26["depend()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| b6fb2fe6_1e20_8aa7_252b_c7c3e62b0e26 f00627f9_f6f9_0415_07cf_adaab8eba795["isRef()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| f00627f9_f6f9_0415_07cf_adaab8eba795 f510a797_01c9_4b79_7634_e77112e3ed58["isShallow()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| f510a797_01c9_4b79_7634_e77112e3ed58 7673a120_6161_8253_592c_2125fb6cfd5d["isReactive()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| 7673a120_6161_8253_592c_2125fb6cfd5d 76b5102d_e435_8761_15f1_bd6e6c57d5a3["traverse()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| 76b5102d_e435_8761_15f1_bd6e6c57d5a3 2a4676b0_3474_8b6b_8cd5_cc83c702bc40["get()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| 2a4676b0_3474_8b6b_8cd5_cc83c702bc40 ba3e2e94_ad22_f194_419c_8e274feb8fdd["queueWatcher()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| ba3e2e94_ad22_f194_419c_8e274feb8fdd eb15026c_5696_e629_0e8f_4bc0a98f7d98["run()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| eb15026c_5696_e629_0e8f_4bc0a98f7d98 548462f9_f5ae_6335_80f2_a5f5b9fdf922["teardown()"] 880ea200_f528_af26_3f6f_c77fc2f21647 -->|calls| 548462f9_f5ae_6335_80f2_a5f5b9fdf922 style 880ea200_f528_af26_3f6f_c77fc2f21647 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
src/v3/apiWatch.ts lines 154–353
function doWatch(
source: WatchSource | WatchSource[] | WatchEffect | object,
cb: WatchCallback | null,
{
immediate,
deep,
flush = 'pre',
onTrack,
onTrigger
}: WatchOptions = emptyObject
): WatchStopHandle {
if (__DEV__ && !cb) {
if (immediate !== undefined) {
warn(
`watch() "immediate" option is only respected when using the ` +
`watch(source, callback, options?) signature.`
)
}
if (deep !== undefined) {
warn(
`watch() "deep" option is only respected when using the ` +
`watch(source, callback, options?) signature.`
)
}
}
const warnInvalidSource = (s: unknown) => {
warn(
`Invalid watch source: ${s}. A watch source can only be a getter/effect ` +
`function, a ref, a reactive object, or an array of these types.`
)
}
const instance = currentInstance
const call = (fn: Function, type: string, args: any[] | null = null) => {
const res = invokeWithErrorHandling(fn, null, args, instance, type)
if (deep && res && res.__ob__) res.__ob__.dep.depend()
return res
}
let getter: () => any
let forceTrigger = false
let isMultiSource = false
if (isRef(source)) {
getter = () => source.value
forceTrigger = isShallow(source)
} else if (isReactive(source)) {
getter = () => {
;(source as any).__ob__.dep.depend()
return source
}
deep = true
} else if (isArray(source)) {
isMultiSource = true
forceTrigger = source.some(s => isReactive(s) || isShallow(s))
getter = () =>
source.map(s => {
if (isRef(s)) {
return s.value
} else if (isReactive(s)) {
s.__ob__.dep.depend()
return traverse(s)
} else if (isFunction(s)) {
return call(s, WATCHER_GETTER)
} else {
__DEV__ && warnInvalidSource(s)
}
})
} else if (isFunction(source)) {
if (cb) {
// getter with cb
getter = () => call(source, WATCHER_GETTER)
} else {
// no cb -> simple effect
getter = () => {
if (instance && instance._isDestroyed) {
return
}
if (cleanup) {
cleanup()
}
return call(source, WATCHER, [onCleanup])
}
}
} else {
getter = noop
__DEV__ && warnInvalidSource(source)
}
if (cb && deep) {
const baseGetter = getter
getter = () => traverse(baseGetter())
}
let cleanup: () => void
let onCleanup: OnCleanup = (fn: () => void) => {
cleanup = watcher.onStop = () => {
call(fn, WATCHER_CLEANUP)
}
}
// in SSR there is no need to setup an actual effect, and it should be noop
// unless it's eager
if (isServerRendering()) {
// we will also not call the invalidate callback (+ runner is not set up)
onCleanup = noop
if (!cb) {
getter()
} else if (immediate) {
call(cb, WATCHER_CB, [
getter(),
isMultiSource ? [] : undefined,
onCleanup
])
}
return noop
}
const watcher = new Watcher(currentInstance, getter, noop, {
lazy: true
})
watcher.noRecurse = !cb
let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE
// overwrite default run
watcher.run = () => {
if (!watcher.active) {
return
}
if (cb) {
// watch(source, cb)
const newValue = watcher.get()
if (
deep ||
forceTrigger ||
(isMultiSource
? (newValue as any[]).some((v, i) =>
hasChanged(v, (oldValue as any[])[i])
)
: hasChanged(newValue, oldValue))
) {
// cleanup before running cb again
if (cleanup) {
cleanup()
}
call(cb, WATCHER_CB, [
newValue,
// pass undefined as the old value when it's changed for the first time
oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
onCleanup
])
oldValue = newValue
}
} else {
// watchEffect
watcher.get()
}
}
if (flush === 'sync') {
watcher.update = watcher.run
} else if (flush === 'post') {
watcher.post = true
watcher.update = () => queueWatcher(watcher)
} else {
// pre
watcher.update = () => {
if (instance && instance === currentInstance && !instance._isMounted) {
// pre-watcher triggered before
const buffer = instance._preWatchers || (instance._preWatchers = [])
if (buffer.indexOf(watcher) < 0) buffer.push(watcher)
} else {
queueWatcher(watcher)
}
}
}
if (__DEV__) {
watcher.onTrack = onTrack
watcher.onTrigger = onTrigger
}
// initial run
if (cb) {
if (immediate) {
watcher.run()
} else {
oldValue = watcher.get()
}
} else if (flush === 'post' && instance) {
instance.$once('hook:mounted', () => watcher.get())
} else {
watcher.get()
}
return () => {
watcher.teardown()
}
}
Domain
Subdomains
Source
Frequently Asked Questions
What does doWatch() do?
doWatch() is a function in the vue codebase.
What does doWatch() call?
doWatch() calls 10 function(s): depend, get, isReactive, isRef, isShallow, queueWatcher, run, teardown, and 2 more.
What calls doWatch()?
doWatch() is called by 4 function(s): watch, watchEffect, watchPostEffect, watchSyncEffect.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free