fix(watch): should not fire pre watcher on child component unmount (#7181)
close #7030
This commit is contained in:
parent
cdac12161e
commit
6784f0b1f8
|
@ -549,6 +549,98 @@ describe('api: watch', () => {
|
||||||
expect(cb).not.toHaveBeenCalled()
|
expect(cb).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #7030
|
||||||
|
it('should not fire on child component unmount w/ flush: pre', async () => {
|
||||||
|
const visible = ref(true)
|
||||||
|
const cb = vi.fn()
|
||||||
|
const Parent = defineComponent({
|
||||||
|
props: ['visible'],
|
||||||
|
render() {
|
||||||
|
return visible.value ? h(Comp) : null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
watch(visible, cb, { flush: 'pre' })
|
||||||
|
},
|
||||||
|
render() {}
|
||||||
|
}
|
||||||
|
const App = {
|
||||||
|
render() {
|
||||||
|
return h(Parent, {
|
||||||
|
visible: visible.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render(h(App), nodeOps.createElement('div'))
|
||||||
|
expect(cb).not.toHaveBeenCalled()
|
||||||
|
visible.value = false
|
||||||
|
await nextTick()
|
||||||
|
expect(cb).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
// #7030
|
||||||
|
it('flush: pre watcher in child component should not fire before parent update', async () => {
|
||||||
|
const b = ref(0)
|
||||||
|
const calls: string[] = []
|
||||||
|
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
watch(
|
||||||
|
() => b.value,
|
||||||
|
val => {
|
||||||
|
calls.push('watcher child')
|
||||||
|
},
|
||||||
|
{ flush: 'pre' }
|
||||||
|
)
|
||||||
|
return () => {
|
||||||
|
b.value
|
||||||
|
calls.push('render child')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Parent = {
|
||||||
|
props: ['a'],
|
||||||
|
setup() {
|
||||||
|
watch(
|
||||||
|
() => b.value,
|
||||||
|
val => {
|
||||||
|
calls.push('watcher parent')
|
||||||
|
},
|
||||||
|
{ flush: 'pre' }
|
||||||
|
)
|
||||||
|
return () => {
|
||||||
|
b.value
|
||||||
|
calls.push('render parent')
|
||||||
|
return h(Comp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const App = {
|
||||||
|
render() {
|
||||||
|
return h(Parent, {
|
||||||
|
a: b.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(h(App), nodeOps.createElement('div'))
|
||||||
|
expect(calls).toEqual(['render parent', 'render child'])
|
||||||
|
|
||||||
|
b.value++
|
||||||
|
await nextTick()
|
||||||
|
expect(calls).toEqual([
|
||||||
|
'render parent',
|
||||||
|
'render child',
|
||||||
|
'watcher parent',
|
||||||
|
'render parent',
|
||||||
|
'watcher child',
|
||||||
|
'render child'
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
// #1763
|
// #1763
|
||||||
it('flush: pre watcher watching props should fire before child update', async () => {
|
it('flush: pre watcher watching props should fire before child update', async () => {
|
||||||
const a = ref(0)
|
const a = ref(0)
|
||||||
|
|
|
@ -1582,7 +1582,7 @@ function baseCreateRenderer(
|
||||||
pauseTracking()
|
pauseTracking()
|
||||||
// props update may have triggered pre-flush watchers.
|
// props update may have triggered pre-flush watchers.
|
||||||
// flush them before the render update.
|
// flush them before the render update.
|
||||||
flushPreFlushCbs()
|
flushPreFlushCbs(instance)
|
||||||
resetTracking()
|
resetTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@ export function queuePostFlushCb(cb: SchedulerJobs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flushPreFlushCbs(
|
export function flushPreFlushCbs(
|
||||||
|
instance?: ComponentInternalInstance,
|
||||||
seen?: CountMap,
|
seen?: CountMap,
|
||||||
// if currently flushing, skip the current job itself
|
// if currently flushing, skip the current job itself
|
||||||
i = isFlushing ? flushIndex + 1 : 0
|
i = isFlushing ? flushIndex + 1 : 0
|
||||||
|
@ -149,6 +150,9 @@ export function flushPreFlushCbs(
|
||||||
for (; i < queue.length; i++) {
|
for (; i < queue.length; i++) {
|
||||||
const cb = queue[i]
|
const cb = queue[i]
|
||||||
if (cb && cb.pre) {
|
if (cb && cb.pre) {
|
||||||
|
if (instance && cb.id !== instance.uid) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (__DEV__ && checkRecursiveUpdates(seen!, cb)) {
|
if (__DEV__ && checkRecursiveUpdates(seen!, cb)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue