]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip(vapor): updated/beforeUpdate
authorEvan You <evan@vuejs.org>
Thu, 5 Dec 2024 16:55:00 +0000 (00:55 +0800)
committerEvan You <evan@vuejs.org>
Thu, 5 Dec 2024 16:55:00 +0000 (00:55 +0800)
packages/runtime-vapor/src/component.ts
packages/runtime-vapor/src/componentProps.ts
packages/runtime-vapor/src/dom/element.ts
packages/runtime-vapor/src/renderEffect.ts

index 96f5552f9f53d967f4823b57ddc700985a4c093f..af42304c20b0a76c1eec22661645e90b3e6b6a86 100644 (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
index 1fca42bfd5837f30aaf4338661ed62a01caec1e1..ff941d2ec5e45ada72e515e2c6e123ceb0acda95 100644 (file)
@@ -255,5 +255,5 @@ export function setupPropsValidation(instance: VaporComponentInstance): void {
       normalizePropsOptions(instance.type)[0]!,
     )
     popWarningContext()
-  })
+  }, true /* noLifecycle */)
 }
index 5c8171b8fc433f6a19253397f1ee9e2d7d79604f..250a99e66aa9d28f325ce0bf546a5740f80de71e 100644 (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)
index 6721661a03e9de8a954ea5a4029964bcc782ac13..17128d23376499fbde8a25c518d4b4d7e17078cd 100644 (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()