diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index b0c8a3f2bba..edc63ac9ae4 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -236,6 +236,12 @@ export function createAppAPI( mixin(mixin: ComponentOptions) { if (__FEATURE_OPTIONS_API__) { if (!context.mixins.includes(mixin)) { + for (let m in mixin) { + if (isFunction(mixin[m])) { + // mark globalMixin + mixin[m]._isGlobalMixin = true + } + } context.mixins.push(mixin) } else if (__DEV__) { warn( diff --git a/packages/runtime-core/src/apiLifecycle.ts b/packages/runtime-core/src/apiLifecycle.ts index ec39308eea5..e7b96175ec2 100644 --- a/packages/runtime-core/src/apiLifecycle.ts +++ b/packages/runtime-core/src/apiLifecycle.ts @@ -14,18 +14,23 @@ import { DebuggerEvent, pauseTracking, resetTracking } from '@vue/reactivity' export { onActivated, onDeactivated } from './components/KeepAlive' +export type WRAPPEDHOOK = { + (hook: Function & { __weh?: WRAPPEDHOOK; _isGlobalMixin?: boolean }): void + _isGlobalMixin?: boolean +} + export function injectHook( type: LifecycleHooks, - hook: Function & { __weh?: Function }, + hook: Function & { __weh?: WRAPPEDHOOK; _isGlobalMixin?: boolean }, target: ComponentInternalInstance | null = currentInstance, prepend: boolean = false -): Function | undefined { +): WRAPPEDHOOK | undefined { if (target) { const hooks = target[type] || (target[type] = []) // cache the error handling wrapper for injected hooks so the same hook // can be properly deduped by the scheduler. "__weh" stands for "with error // handling". - const wrappedHook = + const wrappedHook: WRAPPEDHOOK = hook.__weh || (hook.__weh = (...args: unknown[]) => { if (target.isUnmounted) { @@ -43,8 +48,22 @@ export function injectHook( resetTracking() return res }) + if (hook._isGlobalMixin) { + wrappedHook._isGlobalMixin = hook._isGlobalMixin + } if (prepend) { - hooks.unshift(wrappedHook) + let index = -1 + for (let i = hooks.length - 1; i >= 0; i--) { + if ((hooks[i] as WRAPPEDHOOK)._isGlobalMixin) { + index = i + break + } + } + if (index === -1) { + hooks.unshift(wrappedHook) + } else { + hooks.splice(index + 1, 0, wrappedHook) + } } else { hooks.push(wrappedHook) } @@ -63,12 +82,17 @@ export function injectHook( } } +export interface HOOK { + (e: DebuggerEvent): void + _isGlobalMixin?: boolean +} + export const createHook = - any>(lifecycle: LifecycleHooks) => + (lifecycle: LifecycleHooks) => (hook: T, target: ComponentInternalInstance | null = currentInstance) => // post-create lifecycle registrations are noops during SSR (except for serverPrefetch) (!isInSSRComponentSetup || lifecycle === LifecycleHooks.SERVER_PREFETCH) && - injectHook(lifecycle, hook, target) + injectHook(lifecycle, hook, target, hook._isGlobalMixin ? true : false) export const onBeforeMount = createHook(LifecycleHooks.BEFORE_MOUNT) export const onMounted = createHook(LifecycleHooks.MOUNTED) @@ -86,11 +110,12 @@ export const onRenderTracked = createHook( LifecycleHooks.RENDER_TRACKED ) -export type ErrorCapturedHook = ( - err: TError, - instance: ComponentPublicInstance | null, - info: string -) => boolean | void +export type ErrorCapturedHook = { + (err: TError, instance: ComponentPublicInstance | null, info: string): + | boolean + | void + _isGlobalMixin?: boolean +} export function onErrorCaptured( hook: ErrorCapturedHook, diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index c482d051965..24c481355ee 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -42,7 +42,8 @@ import { onRenderTriggered, DebuggerHook, ErrorCapturedHook, - onServerPrefetch + onServerPrefetch, + HOOK } from './apiLifecycle' import { reactive, @@ -756,12 +757,22 @@ export function applyOptions(instance: ComponentInternalInstance) { function registerLifecycleHook( register: Function, - hook?: Function | Function[] + hook?: HOOK | HOOK[] | ErrorCapturedHook | ErrorCapturedHook[] ) { if (isArray(hook)) { - hook.forEach(_hook => register(_hook.bind(publicThis))) + hook.forEach(_hook => { + const bind = _hook.bind(publicThis) + if (_hook._isGlobalMixin) { + bind._isGlobalMixin = true + } + register(bind) + }) } else if (hook) { - register((hook as Function).bind(publicThis)) + const bind = hook.bind(publicThis) + if (hook._isGlobalMixin) { + bind._isGlobalMixin = true + } + register(bind) } } diff --git a/packages/runtime-core/src/components/KeepAlive.ts b/packages/runtime-core/src/components/KeepAlive.ts index 4b2c7288581..be568c9f5d0 100644 --- a/packages/runtime-core/src/components/KeepAlive.ts +++ b/packages/runtime-core/src/components/KeepAlive.ts @@ -21,7 +21,8 @@ import { injectHook, onUnmounted, onMounted, - onUpdated + onUpdated, + WRAPPEDHOOK } from '../apiLifecycle' import { isString, @@ -407,7 +408,7 @@ function registerKeepAliveHook( } function injectToKeepAliveRoot( - hook: Function & { __weh?: Function }, + hook: Function & { __weh?: WRAPPEDHOOK; _isGlobalMixin?: boolean }, type: LifecycleHooks, target: ComponentInternalInstance, keepAliveRoot: ComponentInternalInstance pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy