From: Evan You Date: Thu, 5 Dec 2024 16:55:00 +0000 (+0800) Subject: wip(vapor): updated/beforeUpdate X-Git-Tag: v3.6.0-alpha.1~16^2~226 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=30e24ce9867f0ac1e6dc6cf44ae28798724a330d;p=thirdparty%2Fvuejs%2Fcore.git wip(vapor): updated/beforeUpdate --- diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 96f5552f9f..af42304c20 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -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 diff --git a/packages/runtime-vapor/src/componentProps.ts b/packages/runtime-vapor/src/componentProps.ts index 1fca42bfd5..ff941d2ec5 100644 --- a/packages/runtime-vapor/src/componentProps.ts +++ b/packages/runtime-vapor/src/componentProps.ts @@ -255,5 +255,5 @@ export function setupPropsValidation(instance: VaporComponentInstance): void { normalizePropsOptions(instance.type)[0]!, ) popWarningContext() - }) + }, true /* noLifecycle */) } diff --git a/packages/runtime-vapor/src/dom/element.ts b/packages/runtime-vapor/src/dom/element.ts index 5c8171b8fc..250a99e66a 100644 --- a/packages/runtime-vapor/src/dom/element.ts +++ b/packages/runtime-vapor/src/dom/element.ts @@ -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) diff --git a/packages/runtime-vapor/src/renderEffect.ts b/packages/runtime-vapor/src/renderEffect.ts index 6721661a03..17128d2337 100644 --- a/packages/runtime-vapor/src/renderEffect.ts +++ b/packages/runtime-vapor/src/renderEffect.ts @@ -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()