feat(runtime-core): watchSyncEffect
This commit is contained in:
parent
33c2fbfdc8
commit
d87d059ac1
@ -16,7 +16,9 @@ import {
|
|||||||
serializeInner,
|
serializeInner,
|
||||||
TestElement,
|
TestElement,
|
||||||
h,
|
h,
|
||||||
createApp
|
createApp,
|
||||||
|
watchPostEffect,
|
||||||
|
watchSyncEffect
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import {
|
import {
|
||||||
ITERATE_KEY,
|
ITERATE_KEY,
|
||||||
@ -28,7 +30,6 @@ import {
|
|||||||
Ref,
|
Ref,
|
||||||
effectScope
|
effectScope
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
import { watchPostEffect } from '../src/apiWatch'
|
|
||||||
|
|
||||||
// reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
|
// reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
|
||||||
|
|
||||||
@ -444,6 +445,48 @@ describe('api: watch', () => {
|
|||||||
expect(result2).toBe(true)
|
expect(result2).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('watchSyncEffect', async () => {
|
||||||
|
const count = ref(0)
|
||||||
|
const count2 = ref(0)
|
||||||
|
|
||||||
|
let callCount = 0
|
||||||
|
let result1
|
||||||
|
let result2
|
||||||
|
const assertion = jest.fn(count => {
|
||||||
|
callCount++
|
||||||
|
// on mount, the watcher callback should be called before DOM render
|
||||||
|
// on update, should be called before the count is updated
|
||||||
|
const expectedDOM = callCount === 1 ? `` : `${count - 1}`
|
||||||
|
result1 = serializeInner(root) === expectedDOM
|
||||||
|
|
||||||
|
// in a sync callback, state mutation on the next line should not have
|
||||||
|
// executed yet on the 2nd call, but will be on the 3rd call.
|
||||||
|
const expectedState = callCount < 3 ? 0 : 1
|
||||||
|
result2 = count2.value === expectedState
|
||||||
|
})
|
||||||
|
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
watchSyncEffect(() => {
|
||||||
|
assertion(count.value)
|
||||||
|
})
|
||||||
|
return () => count.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Comp), root)
|
||||||
|
expect(assertion).toHaveBeenCalledTimes(1)
|
||||||
|
expect(result1).toBe(true)
|
||||||
|
expect(result2).toBe(true)
|
||||||
|
|
||||||
|
count.value++
|
||||||
|
count2.value++
|
||||||
|
await nextTick()
|
||||||
|
expect(assertion).toHaveBeenCalledTimes(3)
|
||||||
|
expect(result1).toBe(true)
|
||||||
|
expect(result2).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('should not fire on component unmount w/ flush: post', async () => {
|
it('should not fire on component unmount w/ flush: post', async () => {
|
||||||
const toggle = ref(true)
|
const toggle = ref(true)
|
||||||
const cb = jest.fn()
|
const cb = jest.fn()
|
||||||
|
@ -96,6 +96,19 @@ export function watchPostEffect(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function watchSyncEffect(
|
||||||
|
effect: WatchEffect,
|
||||||
|
options?: DebuggerOptions
|
||||||
|
) {
|
||||||
|
return doWatch(
|
||||||
|
effect,
|
||||||
|
null,
|
||||||
|
(__DEV__
|
||||||
|
? Object.assign(options || {}, { flush: 'sync' })
|
||||||
|
: { flush: 'sync' }) as WatchOptionsBase
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// initial value for watchers to trigger on undefined initial values
|
// initial value for watchers to trigger on undefined initial values
|
||||||
const INITIAL_WATCHER_VALUE = {}
|
const INITIAL_WATCHER_VALUE = {}
|
||||||
|
|
||||||
|
@ -34,7 +34,12 @@ export {
|
|||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
onScopeDispose
|
onScopeDispose
|
||||||
} from '@vue/reactivity'
|
} from '@vue/reactivity'
|
||||||
export { watch, watchEffect, watchPostEffect } from './apiWatch'
|
export {
|
||||||
|
watch,
|
||||||
|
watchEffect,
|
||||||
|
watchPostEffect,
|
||||||
|
watchSyncEffect
|
||||||
|
} from './apiWatch'
|
||||||
export {
|
export {
|
||||||
onBeforeMount,
|
onBeforeMount,
|
||||||
onMounted,
|
onMounted,
|
||||||
|
Loading…
Reference in New Issue
Block a user