h,
createApp,
watchPostEffect,
- watchSyncEffect
+ watchSyncEffect,
+ onMounted
} from '@vue/runtime-test'
import {
ITERATE_KEY,
expect(calls).toEqual(['render', 'watcher 1', 'watcher 2', 'render'])
})
+ // #5721
+ it('flush: pre triggered in component setup should be buffered and called before mounted', () => {
+ const count = ref(0)
+ const calls: string[] = []
+ const App = {
+ render() {},
+ setup() {
+ watch(
+ count,
+ () => {
+ calls.push('watch ' + count.value)
+ },
+ { flush: 'pre' }
+ )
+ onMounted(() => {
+ calls.push('mounted')
+ })
+ // mutate multiple times
+ count.value++
+ count.value++
+ count.value++
+ }
+ }
+ render(h(App), nodeOps.createElement('div'))
+ expect(calls).toMatchObject(['watch 3', 'mounted'])
+ })
+
// #1852
it('flush: post watcher should fire after template refs updated', async () => {
const toggle = ref(false)
scheduler = () => queuePostRenderEffect(job, instance && instance.suspense)
} else {
// default: 'pre'
- scheduler = () => {
- if (!instance || instance.isMounted) {
- queuePreFlushCb(job)
- } else {
- // with 'pre' option, the first call must happen before
- // the component is mounted so it is called synchronously.
- job()
- }
- }
+ scheduler = () => queuePreFlushCb(job)
}
const effect = new ReactiveEffect(getter, scheduler)
}
export function flushPostFlushCbs(seen?: CountMap) {
+ // flush any pre cbs queued during the flush (e.g. pre watchers)
+ flushPreFlushCbs()
if (pendingPostFlushCbs.length) {
const deduped = [...new Set(pendingPostFlushCbs)]
pendingPostFlushCbs.length = 0