doWatch() — vue Function Reference
Architecture documentation for the doWatch() function in apiWatch.ts from the vue codebase.
Entity Profile
Dependency Diagram
graph TD b2856354_51ef_6ef1_ec4b_ae2e72186601["doWatch()"] 0bfbb910_39a9_6fb2_a13f_4bd26024d513["watchEffect()"] 0bfbb910_39a9_6fb2_a13f_4bd26024d513 -->|calls| b2856354_51ef_6ef1_ec4b_ae2e72186601 8c4927dd_5736_4f48_c149_40b7d44316c9["watchPostEffect()"] 8c4927dd_5736_4f48_c149_40b7d44316c9 -->|calls| b2856354_51ef_6ef1_ec4b_ae2e72186601 3430a392_62b0_9796_2cea_f117f44bb539["watchSyncEffect()"] 3430a392_62b0_9796_2cea_f117f44bb539 -->|calls| b2856354_51ef_6ef1_ec4b_ae2e72186601 3cbf8aba_5563_0e8d_9c9d_e4f8166bfefb["watch()"] 3cbf8aba_5563_0e8d_9c9d_e4f8166bfefb -->|calls| b2856354_51ef_6ef1_ec4b_ae2e72186601 3cbf8aba_5563_0e8d_9c9d_e4f8166bfefb["watch()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| 3cbf8aba_5563_0e8d_9c9d_e4f8166bfefb d1eb6d83_f4fb_7e95_6bf0_bea3d8b0996f["depend()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| d1eb6d83_f4fb_7e95_6bf0_bea3d8b0996f 1cb75796_39e2_4190_8602_3712ff6cf2f7["isRef()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| 1cb75796_39e2_4190_8602_3712ff6cf2f7 a641b7eb_3a6c_54f5_9c98_7b09f54970d3["isShallow()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| a641b7eb_3a6c_54f5_9c98_7b09f54970d3 c5c37a47_bc5f_b7a2_7788_aa7ab748702f["isReactive()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| c5c37a47_bc5f_b7a2_7788_aa7ab748702f a1748d17_4487_c7f1_cd6f_4b967a12f725["traverse()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| a1748d17_4487_c7f1_cd6f_4b967a12f725 c595e491_455c_5f96_1a90_ed59c627158b["get()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| c595e491_455c_5f96_1a90_ed59c627158b a5f84bab_9034_ce7b_6911_25c506039541["queueWatcher()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| a5f84bab_9034_ce7b_6911_25c506039541 df67762e_53ee_05bf_1358_c48dd0fc8f8d["run()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| df67762e_53ee_05bf_1358_c48dd0fc8f8d 3d03878c_4a3a_4d94_b9f5_3c7287192b05["teardown()"] b2856354_51ef_6ef1_ec4b_ae2e72186601 -->|calls| 3d03878c_4a3a_4d94_b9f5_3c7287192b05 style b2856354_51ef_6ef1_ec4b_ae2e72186601 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