Quellcode durchsuchen

feat(runtime-core): implement debug hook (#183)

GaoNeng vor 2 Jahren
Ursprung
Commit
d6c5bcf833

+ 45 - 0
packages/runtime-vapor/__tests__/apiLifecycle.spec.ts

@@ -6,6 +6,8 @@ import {
   getCurrentInstance,
   inject,
   nextTick,
+  onRenderTracked,
+  onRenderTriggered,
   onUpdated,
   provide,
   ref,
@@ -112,4 +114,47 @@ describe('apiLifecycle', () => {
     expect(handleUpdated).toHaveBeenCalledTimes(1)
     expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
   })
+
+  test('onRenderTracked', async () => {
+    const onTrackedFn = vi.fn()
+    const count = ref(0)
+    const { host, render } = define({
+      setup() {
+        onRenderTracked(onTrackedFn)
+        return (() => {
+          const n0 = createTextNode()
+          renderEffect(() => {
+            setText(n0, count.value)
+          })
+          return n0
+        })()
+      },
+    })
+    render()
+    await nextTick()
+    expect(onTrackedFn).toBeCalled()
+    expect(host.innerHTML).toBe('0')
+  })
+  test('onRenderTrigger', async () => {
+    const onRenderTriggerFn = vi.fn()
+    const count = ref(0)
+    const { host, render } = define({
+      setup() {
+        onRenderTriggered(onRenderTriggerFn)
+        return (() => {
+          const n0 = createTextNode()
+          renderEffect(() => {
+            setText(n0, count.value)
+          })
+          return n0
+        })()
+      },
+    })
+    render()
+    count.value++
+    await nextTick()
+    expect(onRenderTriggerFn).toBeCalled()
+    expect(onRenderTriggerFn).toHaveBeenCalledOnce()
+    expect(host.innerHTML).toBe('1')
+  })
 })

+ 13 - 1
packages/runtime-vapor/src/apiLifecycle.ts

@@ -4,7 +4,11 @@ import {
   setCurrentInstance,
 } from './component'
 import { warn } from './warning'
-import { pauseTracking, resetTracking } from '@vue/reactivity'
+import {
+  type DebuggerEvent,
+  pauseTracking,
+  resetTracking,
+} from '@vue/reactivity'
 import { ErrorTypeStrings, callWithAsyncErrorHandling } from './errorHandling'
 import { toHandlerKey } from '@vue/shared'
 
@@ -77,6 +81,14 @@ export const onUpdated = createHook(VaporLifecycleHooks.UPDATED)
 export const onBeforeUnmount = createHook(VaporLifecycleHooks.BEFORE_UNMOUNT)
 export const onUnmounted = createHook(VaporLifecycleHooks.UNMOUNTED)
 
+export type DebuggerHook = (e: DebuggerEvent) => void
+export const onRenderTriggered = createHook<DebuggerHook>(
+  VaporLifecycleHooks.RENDER_TRIGGERED,
+)
+export const onRenderTracked = createHook<DebuggerHook>(
+  VaporLifecycleHooks.RENDER_TRACKED,
+)
+
 export type ErrorCapturedHook<TError = unknown> = (
   err: TError,
   instance: ComponentInternalInstance | null,

+ 2 - 2
packages/runtime-vapor/src/index.ts

@@ -106,8 +106,8 @@ export {
   onUnmounted,
   // onActivated,
   // onDeactivated,
-  // onRenderTracked,
-  // onRenderTriggered,
+  onRenderTracked,
+  onRenderTriggered,
   onErrorCaptured,
   // onServerPrefetch,
 } from './apiLifecycle'

+ 8 - 2
packages/runtime-vapor/src/renderEffect.ts

@@ -18,7 +18,6 @@ import { invokeDirectiveHook } from './directives'
 export function renderEffect(cb: () => void) {
   const instance = getCurrentInstance()
   const scope = getCurrentScope()
-
   let effect: ReactiveEffect
 
   const job: SchedulerJob = () => {
@@ -77,7 +76,14 @@ export function renderEffect(cb: () => void) {
     if (instance) job.id = instance.uid
     queueJob(job)
   }
-
+  if (__DEV__) {
+    effect.onTrack = instance?.rtc
+      ? e => invokeArrayFns(instance.rtc!, e)
+      : void 0
+    effect.onTrigger = instance?.rtg
+      ? e => invokeArrayFns(instance.rtg!, e)
+      : void 0
+  }
   effect.run()
 }
 

+ 9 - 0
playground/src/App.vue

@@ -7,6 +7,8 @@ import {
   getCurrentInstance,
   onBeforeUpdate,
   onUpdated,
+  onRenderTracked,
+  onRenderTriggered,
 } from 'vue/vapor'
 
 const instance = getCurrentInstance()!
@@ -36,6 +38,13 @@ onUpdated(() => {
   console.log('updated')
 })
 
+onRenderTracked(e => {
+  console.log(`Render Tracked:`, e.target)
+})
+onRenderTriggered(e => {
+  console.log(`Render trigger:`, e.target)
+})
+
 const log = (arg: any) => {
   console.log('callback in render effect')
   return arg