mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
parent
46ec648694
commit
25ffdb62d2
@ -59,6 +59,15 @@ if (inBrowser && !isIE) {
|
||||
}
|
||||
}
|
||||
|
||||
const sortCompareFn = (a: Watcher, b: Watcher): number => {
|
||||
if (a.post) {
|
||||
if (!b.post) return 1
|
||||
} else if (b.post) {
|
||||
return -1
|
||||
}
|
||||
return a.id - b.id
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush both queues and run the watchers.
|
||||
*/
|
||||
@ -75,7 +84,7 @@ function flushSchedulerQueue() {
|
||||
// user watchers are created before the render watcher)
|
||||
// 3. If a component is destroyed during a parent component's watcher run,
|
||||
// its watchers can be skipped.
|
||||
queue.sort((a, b) => a.id - b.id)
|
||||
queue.sort(sortCompareFn)
|
||||
|
||||
// do not cache length because more watchers might be pushed
|
||||
// as we run existing watchers
|
||||
|
@ -58,6 +58,7 @@ export default class Watcher implements DepTarget {
|
||||
noRecurse?: boolean
|
||||
getter: Function
|
||||
value: any
|
||||
post: boolean
|
||||
|
||||
// dev only
|
||||
onTrack?: ((event: DebuggerEvent) => void) | undefined
|
||||
@ -93,6 +94,7 @@ export default class Watcher implements DepTarget {
|
||||
this.cb = cb
|
||||
this.id = ++uid // uid for batching
|
||||
this.active = true
|
||||
this.post = false
|
||||
this.dirty = this.lazy // for lazy watchers
|
||||
this.deps = []
|
||||
this.newDeps = []
|
||||
|
@ -313,7 +313,7 @@ function doWatch(
|
||||
if (flush === 'sync') {
|
||||
watcher.update = watcher.run
|
||||
} else if (flush === 'post') {
|
||||
watcher.id = Infinity
|
||||
watcher.post = true
|
||||
watcher.update = () => queueWatcher(watcher)
|
||||
} else {
|
||||
// pre
|
||||
|
@ -1167,4 +1167,37 @@ describe('api: watch', () => {
|
||||
set(r.value, 'foo', 1)
|
||||
expect(spy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
// #12664
|
||||
it('queueing multiple flush: post watchers', async () => {
|
||||
const parentSpy = vi.fn()
|
||||
const childSpy = vi.fn()
|
||||
|
||||
const Child = {
|
||||
setup() {
|
||||
const el = ref()
|
||||
watch(el, childSpy, { flush: 'post' })
|
||||
return { el }
|
||||
},
|
||||
template: `<div><span ref="el">hello child</span></div>`
|
||||
}
|
||||
const App = {
|
||||
components: { Child },
|
||||
setup() {
|
||||
const el = ref()
|
||||
watch(el, parentSpy, { flush: 'post' })
|
||||
return { el }
|
||||
},
|
||||
template: `<div><Child /><span ref="el">hello app1</span></div>`
|
||||
}
|
||||
|
||||
const container = document.createElement('div')
|
||||
const root = document.createElement('div')
|
||||
container.appendChild(root)
|
||||
new Vue(App).$mount(root)
|
||||
|
||||
await nextTick()
|
||||
expect(parentSpy).toHaveBeenCalledTimes(1)
|
||||
expect(childSpy).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user