Skip to content

Commit 58b0706

Browse files
committed
fix(watch): stop instance-bound watchers in post render queue
so that changes triggered in beforeUnmount get correct value in callback fix #1525
1 parent 41db49d commit 58b0706

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

packages/runtime-core/src/apiWatch.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
callWithErrorHandling,
3030
callWithAsyncErrorHandling
3131
} from './errorHandling'
32-
import { onBeforeUnmount } from './apiLifecycle'
3332
import { queuePostRenderEffect } from './renderer'
3433
import { warn } from './warning'
3534

@@ -134,7 +133,8 @@ export function watch<T = any>(
134133
function doWatch(
135134
source: WatchSource | WatchSource[] | WatchEffect,
136135
cb: WatchCallback | null,
137-
{ immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
136+
{ immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ,
137+
instance = currentInstance
138138
): WatchStopHandle {
139139
if (__DEV__ && !cb) {
140140
if (immediate !== undefined) {
@@ -160,8 +160,6 @@ function doWatch(
160160
)
161161
}
162162

163-
const instance = currentInstance
164-
165163
let getter: () => any
166164
if (isArray(source)) {
167165
getter = () =>
@@ -316,9 +314,7 @@ export function instanceWatch(
316314
const getter = isString(source)
317315
? () => publicThis[source]
318316
: source.bind(publicThis)
319-
const stop = watch(getter, cb.bind(publicThis), options)
320-
onBeforeUnmount(stop, this)
321-
return stop
317+
return doWatch(getter, cb.bind(publicThis), options, this)
322318
}
323319

324320
function traverse(value: unknown, seen: Set<unknown> = new Set()) {

packages/runtime-core/src/renderer.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1996,17 +1996,19 @@ function baseCreateRenderer(
19961996
if (bum) {
19971997
invokeArrayFns(bum)
19981998
}
1999-
if (effects) {
2000-
for (let i = 0; i < effects.length; i++) {
2001-
stop(effects[i])
2002-
}
2003-
}
20041999
// update may be null if a component is unmounted before its async
20052000
// setup has resolved.
20062001
if (update) {
20072002
stop(update)
20082003
unmount(subTree, instance, parentSuspense, doRemove)
20092004
}
2005+
if (effects) {
2006+
queuePostRenderEffect(() => {
2007+
for (let i = 0; i < effects.length; i++) {
2008+
stop(effects[i])
2009+
}
2010+
}, parentSuspense)
2011+
}
20102012
// unmounted hook
20112013
if (um) {
20122014
queuePostRenderEffect(um, parentSuspense)

0 commit comments

Comments
 (0)