wip(vapor): updated/beforeUpdate

This commit is contained in:
Evan You 2024-12-06 00:55:00 +08:00
parent 5d860276db
commit 30e24ce986
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
4 changed files with 54 additions and 12 deletions

View File

@ -185,6 +185,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
isMounted: boolean
isUnmounted: boolean
isDeactivated: boolean
isUpdating: boolean
bc?: LifecycleHook // LifecycleHooks.BEFORE_CREATE
c?: LifecycleHook // LifecycleHooks.CREATED
@ -223,7 +224,11 @@ export class VaporComponentInstance implements GenericComponentInstance {
: Object.create(this.appContext.provides)
this.refs = EMPTY_OBJ
this.emitted = this.ec = this.exposed = this.propsDefaults = null
this.isMounted = this.isUnmounted = this.isDeactivated = false
this.isMounted =
this.isUnmounted =
this.isUpdating =
this.isDeactivated =
false
// init props
const target = rawProps || EMPTY_OBJ

View File

@ -255,5 +255,5 @@ export function setupPropsValidation(instance: VaporComponentInstance): void {
normalizePropsOptions(instance.type)[0]!,
)
popWarningContext()
})
}, true /* noLifecycle */)
}

View File

@ -12,9 +12,14 @@ export function insert(
if (block instanceof Node) {
parent.insertBefore(block, anchor)
} else if (isVaporComponent(block)) {
if (block.bm) invokeArrayFns(block.bm)
insert(block.block, parent, anchor)
if (block.m) invokeArrayFns(block.m)
if (!block.isMounted) {
if (block.bm) invokeArrayFns(block.bm)
insert(block.block, parent, anchor)
if (block.m) invokeArrayFns(block.m)
block.isMounted = true
} else {
insert(block.block, parent, anchor)
}
} else if (isArray(block)) {
for (let i = 0; i < block.length; i++) {
insert(block[i], parent, anchor)

View File

@ -1,14 +1,46 @@
import { ReactiveEffect } from '@vue/reactivity'
import { type SchedulerJob, currentInstance, queueJob } from '@vue/runtime-dom'
import {
type SchedulerJob,
currentInstance,
queueJob,
queuePostFlushCb,
setCurrentInstance,
warn,
} from '@vue/runtime-dom'
import { type VaporComponentInstance, isVaporComponent } from './component'
import { invokeArrayFns } from '@vue/shared'
export function renderEffect(fn: () => void): void {
const updateFn = () => {
fn()
export function renderEffect(fn: () => void, noLifecycle = false): void {
const instance = currentInstance as VaporComponentInstance
if (__DEV__ && !isVaporComponent(instance)) {
warn('renderEffect called without active vapor instance.')
}
const effect = new ReactiveEffect(updateFn)
const effect = new ReactiveEffect(
noLifecycle
? fn
: () => {
const reset = setCurrentInstance(instance)
const { isMounted, isUpdating, bu, u } = instance
// before update
if (isMounted && !isUpdating && (bu || u)) {
instance.isUpdating = true
bu && invokeArrayFns(bu)
fn()
queuePostFlushCb(() => {
instance.isUpdating = false
u && invokeArrayFns(u)
})
} else {
fn()
}
reset()
},
)
const job: SchedulerJob = effect.runIfDirty.bind(effect)
job.i = currentInstance as any
job.id = currentInstance!.uid
job.i = instance
job.id = instance.uid
effect.scheduler = () => queueJob(job)
effect.run()