2024-04-15 02:58:32 +08:00
|
|
|
import {
|
|
|
|
|
EffectFlags,
|
|
|
|
|
ReactiveEffect,
|
|
|
|
|
type SchedulerJob,
|
|
|
|
|
SchedulerJobFlags,
|
2024-04-16 16:55:44 +08:00
|
|
|
getCurrentScope,
|
2024-04-15 02:58:32 +08:00
|
|
|
} from '@vue/reactivity'
|
2024-03-18 20:13:40 +08:00
|
|
|
import { invokeArrayFns } from '@vue/shared'
|
2024-04-15 02:58:32 +08:00
|
|
|
import {
|
|
|
|
|
type ComponentInternalInstance,
|
|
|
|
|
getCurrentInstance,
|
|
|
|
|
setCurrentInstance,
|
|
|
|
|
} from './component'
|
2024-04-19 16:19:56 +08:00
|
|
|
import { queueJob, queuePostFlushCb } from './scheduler'
|
2024-03-18 20:13:40 +08:00
|
|
|
import { VaporErrorCodes, callWithAsyncErrorHandling } from './errorHandling'
|
|
|
|
|
import { invokeDirectiveHook } from './directives'
|
|
|
|
|
|
|
|
|
|
export function renderEffect(cb: () => void) {
|
|
|
|
|
const instance = getCurrentInstance()
|
2024-04-16 16:55:44 +08:00
|
|
|
const scope = getCurrentScope()
|
2024-03-18 20:13:40 +08:00
|
|
|
let effect: ReactiveEffect
|
|
|
|
|
|
|
|
|
|
const job: SchedulerJob = () => {
|
|
|
|
|
if (!(effect.flags & EffectFlags.ACTIVE) || !effect.dirty) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 19:09:31 +08:00
|
|
|
if (instance && instance.isMounted && !instance.isUpdating) {
|
2024-03-18 20:13:40 +08:00
|
|
|
instance.isUpdating = true
|
|
|
|
|
|
|
|
|
|
const { bu, u, dirs } = instance
|
|
|
|
|
// beforeUpdate hook
|
|
|
|
|
if (bu) {
|
|
|
|
|
invokeArrayFns(bu)
|
|
|
|
|
}
|
|
|
|
|
if (dirs) {
|
|
|
|
|
invokeDirectiveHook(instance, 'beforeUpdate')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
effect.run()
|
|
|
|
|
|
2024-04-19 16:19:56 +08:00
|
|
|
queuePostFlushCb(() => {
|
2024-03-18 20:13:40 +08:00
|
|
|
instance.isUpdating = false
|
|
|
|
|
if (dirs) {
|
|
|
|
|
invokeDirectiveHook(instance, 'updated')
|
|
|
|
|
}
|
|
|
|
|
// updated hook
|
|
|
|
|
if (u) {
|
2024-04-19 16:19:56 +08:00
|
|
|
queuePostFlushCb(u)
|
2024-03-18 20:13:40 +08:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
effect.run()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 16:55:44 +08:00
|
|
|
if (scope) {
|
|
|
|
|
const baseCb = cb
|
|
|
|
|
cb = () => scope.run(baseCb)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (instance) {
|
|
|
|
|
const baseCb = cb
|
|
|
|
|
cb = () => {
|
|
|
|
|
const reset = setCurrentInstance(instance)
|
|
|
|
|
baseCb()
|
|
|
|
|
reset()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
effect = new ReactiveEffect(() =>
|
|
|
|
|
callWithAsyncErrorHandling(cb, instance, VaporErrorCodes.RENDER_FUNCTION),
|
|
|
|
|
)
|
2024-03-18 20:13:40 +08:00
|
|
|
|
|
|
|
|
effect.scheduler = () => {
|
|
|
|
|
if (instance) job.id = instance.uid
|
|
|
|
|
queueJob(job)
|
|
|
|
|
}
|
2024-05-12 19:09:31 +08:00
|
|
|
if (__DEV__ && instance) {
|
|
|
|
|
effect.onTrack = instance.rtc
|
2024-04-21 20:30:47 +08:00
|
|
|
? e => invokeArrayFns(instance.rtc!, e)
|
|
|
|
|
: void 0
|
2024-05-12 19:09:31 +08:00
|
|
|
effect.onTrigger = instance.rtg
|
2024-04-21 20:30:47 +08:00
|
|
|
? e => invokeArrayFns(instance.rtg!, e)
|
|
|
|
|
: void 0
|
|
|
|
|
}
|
2024-03-18 20:13:40 +08:00
|
|
|
effect.run()
|
|
|
|
|
}
|
2024-04-15 02:58:32 +08:00
|
|
|
|
|
|
|
|
export function firstEffect(
|
|
|
|
|
instance: ComponentInternalInstance,
|
|
|
|
|
fn: () => void,
|
|
|
|
|
) {
|
|
|
|
|
const effect = new ReactiveEffect(fn)
|
|
|
|
|
const job: SchedulerJob = () => effect.run()
|
|
|
|
|
job.flags! |= SchedulerJobFlags.PRE
|
|
|
|
|
job.id = instance.uid
|
|
|
|
|
effect.scheduler = () => queueJob(job)
|
|
|
|
|
effect.run()
|
|
|
|
|
}
|