import { VNode , VNodeChild , isVNode } from './vnode' ; import { pauseTracking , resetTracking , shallowReadonly , proxyRefs , EffectScope , markRaw , track , TrackOpTypes } from '@vue/reactivity' ; import { ComponentPublicInstance , PublicInstanceProxyHandlers , createDevRenderContext , exposePropsOnRenderContext , exposeSetupStateOnRenderContext , ComponentPublicInstanceConstructor , publicPropertiesMap , RuntimeCompiledPublicInstanceProxyHandlers } from './componentPublicInstance' ; import { ComponentPropsOptions , NormalizedPropsOptions , initProps , normalizePropsOptions } from './componentProps' ; import { Slots , initSlots , InternalSlots } from './componentSlots' ; import { warn } from './warning' ; import { ErrorCodes , callWithErrorHandling , handleError } from './errorHandling' ; import { AppContext , createAppContext , AppConfig } from './apiCreateApp' ; import { Directive , validateDirectiveName } from './directives' ; import { applyOptions , ComponentOptions , ComputedOptions , MethodOptions } from './componentOptions' ; import { EmitsOptions , ObjectEmitsOptions , EmitFn , emit , normalizeEmitsOptions } from './componentEmits' ; import { EMPTY_OBJ , isFunction , NOOP , isObject , NO , makeMap , isPromise , ShapeFlags , extend } from '@vue/shared' ; import { SuspenseBoundary } from './components/Suspense' ; import { CompilerOptions } from '@vue/compiler-core' ; import { markAttrsAccessed } from './componentRenderUtils' ; import { currentRenderingInstance } from './componentRenderContext' ; import { startMeasure , endMeasure } from './profiling' ; import { convertLegacyRenderFn } from './compat/renderFn' ; import { globalCompatConfig , validateCompatConfig } from './compat/compatConfig' ; import { SchedulerJob } from './scheduler' ; export type Data = Record < string , unknown > ; /**
 * For extending allowed non-declared props on components in TSX
 */ export interface ComponentCustomProps { } /**
 * Default allowed non-declared props on component in TSX
 */ export interface AllowedComponentProps { class ? : unknown ; style ? : unknown ; } export interface ComponentInternalOptions { internal __scopeId ? : string ; internal __cssModules ? : Data ; internal __hmrId ? : string ; /**
     * Compat build only, for bailing out of certain compatibility behavior
     */ __isBuiltIn ? : boolean ; /**
     * This one should be exposed so that devtools can make use of it
     */ __file ? : string ; } export interface FunctionalComponent < P = { } , E extends EmitsOptions = { } > extends ComponentInternalOptions { ( props , ctx ) : any ; props ? : ComponentPropsOptions < P > ; emits ? : E | ( keyof E ) [ ] ; inheritAttrs ? : boolean ; displayName ? : string ; } export interface ClassComponent { new ( ... args ) : ComponentPublicInstance < any , any , any , any , any > ; __vccOpts : ComponentOptions ; } /**
 * Concrete component type matches its actual value: it's either an options
 * object, or a function. Use this where the code expects to work with actual
 * values, e.g. checking if its a function or not. This is mostly for internal
 * implementation code.
 */ export type ConcreteComponent < Props = { } , RawBindings = any , D = any , C extends ComputedOptions = ComputedOptions , M extends MethodOptions = MethodOptions > = ComponentOptions < Props , RawBindings , D , C , M > | FunctionalComponent < Props , any > ; /**
 * A type used in public APIs where a component type is expected.
 * The constructor type is an artificial type returned by defineComponent().
 */ export type Component < Props = any , RawBindings = any , D = any , C extends ComputedOptions = ComputedOptions , M extends MethodOptions = MethodOptions > = ConcreteComponent < Props , RawBindings , D , C , M > | ComponentPublicInstanceConstructor < Props > ; export { ComponentOptions } ; type LifecycleHook < TFn = Function > = TFn [ ] | null ; export const enum LifecycleHooks { BEFORE_CREATE = 'bc' , CREATED = 'c' , BEFORE_MOUNT = 'bm' , MOUNTED = 'm' , BEFORE_UPDATE = 'bu' , UPDATED = 'u' , BEFORE_UNMOUNT = 'bum' , UNMOUNTED = 'um' , DEACTIVATED = 'da' , ACTIVATED = 'a' , RENDER_TRIGGERED = 'rtg' , RENDER_TRACKED = 'rtc' , ERROR_CAPTURED = 'ec' , SERVER_PREFETCH = 'sp' } export interface SetupContext < E = EmitsOptions > { attrs : Data ; slots : Slots ; emit : EmitFn < E > ; expose : ( exposed ? : Record < string , any > ) => void ; } internal export type InternalRenderFunction = { ( ctx , cache , $props , $setup , $data , $options ) : VNodeChild ; _rc ? : boolean ; _compatChecked ? : boolean ; _compatWrapped ? : boolean ; } ; /**
 * We expose a subset of properties on the internal instance as they are
 * useful for advanced external libraries and tools.
 */ export interface ComponentInternalInstance { uid : number ; type : ConcreteComponent ; parent : ComponentInternalInstance | null ; root : ComponentInternalInstance ; appContext : AppContext ; /**
     * Vnode representing this component in its parent's vdom tree
     */ vnode : VNode ; internal next : VNode | null ; /**
     * Root vnode of this component's own vdom tree
     */ subTree : VNode ; /**
     * Bound effect runner to be passed to schedulers
     */ update : SchedulerJob ; internal render : InternalRenderFunction | null ; internal ssrRender ? : Function | null ; internal provides : Data ; internal scope : EffectScope ; internal accessCache : Data | null ; internal renderCache : ( Function | VNode ) [ ] ; internal components : Record < string , ConcreteComponent > | null ; internal directives : Record < string , Directive > | null ; internal filters ? : Record < string , Function > ; internal propsOptions : NormalizedPropsOptions ; internal emitsOptions : ObjectEmitsOptions | null ; internal inheritAttrs ? : boolean ; /**
     * is custom element?
     */ isCE ? : boolean ; /**
     * custom element specific HMR method
     */ ceReload ? : ( newStyles ? : string [ ] ) => void ; proxy : ComponentPublicInstance | null ; exposed : Record < string , any > | null ; exposeProxy : Record < string , any > | null ; internal withProxy : ComponentPublicInstance | null ; internal ctx : Data ; data : Data ; props : Data ; attrs : Data ; slots : InternalSlots ; refs : Data ; emit : EmitFn ; internal emitted : Record < string , boolean > | null ; internal propsDefaults : Data ; internal setupState : Data ; internal devtoolsRawSetupState ? : any ; internal setupContext : SetupContext | null ; internal suspense : SuspenseBoundary | null ; internal suspenseId : number ; internal asyncDep : Promise < any > | null ; internal asyncResolved : boolean ; isMounted : boolean ; isUnmounted : boolean ; isDeactivated : boolean ; internal [ LifecycleHooks . BEFORE_CREATE ] : LifecycleHook ; internal [ LifecycleHooks . CREATED ] : LifecycleHook ; internal [ LifecycleHooks . BEFORE_MOUNT ] : LifecycleHook ; internal [ LifecycleHooks . MOUNTED ] : LifecycleHook ; internal [ LifecycleHooks . BEFORE_UPDATE ] : LifecycleHook ; internal [ LifecycleHooks . UPDATED ] : LifecycleHook ; internal [ LifecycleHooks . BEFORE_UNMOUNT ] : LifecycleHook ; internal [ LifecycleHooks . UNMOUNTED ] : LifecycleHook ; internal [ LifecycleHooks . RENDER_TRACKED ] : LifecycleHook ; internal [ LifecycleHooks . RENDER_TRIGGERED ] : LifecycleHook ; internal [ LifecycleHooks . ACTIVATED ] : LifecycleHook ; internal [ LifecycleHooks . DEACTIVATED ] : LifecycleHook ; internal [ LifecycleHooks . ERROR_CAPTURED ] : LifecycleHook ; internal [ LifecycleHooks . SERVER_PREFETCH ] : LifecycleHook < ( ) => Promise < unknown > > ; } const emptyAppContext = createAppContext ( ) ; let uid = 0 ; export function createComponentInstance ( vnode , parent , suspense ) { const type = vnode . type as ConcreteComponent ; const appContext = ( parent ? parent . appContext : vnode . appContext ) || emptyAppContext ; const instance = { uid : uid ++ , vnode , type , parent , appContext , root : null ! , next : null , subTree : null ! , update : null ! , scope : new EffectScope ( true ) , render : null , proxy : null , exposed : null , exposeProxy : null , withProxy : null , provides : parent ? parent . provides : Object . create ( appContext . provides ) , accessCache : null ! , renderCache : [ ] , components : null , directives : null , propsOptions : normalizePropsOptions ( type , appContext ) , emitsOptions : normalizeEmitsOptions ( type , appContext ) , emit : null ! , emitted : null , propsDefaults : EMPTY_OBJ , inheritAttrs : type . inheritAttrs , ctx : EMPTY_OBJ , data : EMPTY_OBJ , props : EMPTY_OBJ , attrs : EMPTY_OBJ , slots : EMPTY_OBJ , refs : EMPTY_OBJ , setupState : EMPTY_OBJ , setupContext : null , suspense , suspenseId : suspense ? suspense . pendingId : 0 , asyncDep : null , asyncResolved : false , isMounted : false , isUnmounted : false , isDeactivated : false , bc : null , c : null , bm : null , m : null , bu : null , u : null , um : null , bum : null , da : null , a : null , rtg : null , rtc : null , ec : null , sp : null } ; if ( __DEV__ ) { instance . ctx = createDevRenderContext ( instance ) ; } else { instance . ctx = { _ : instance } ; } instance . root = parent ? parent . root : instance ; instance . emit = emit . bind ( null , instance ) ; if ( vnode . ce ) { vnode . ce ( instance ) ; } return instance ; } export let currentInstance = null ; export const getCurrentInstance = ( ) => currentInstance || currentRenderingInstance ; export const setCurrentInstance = ( instance ) => { currentInstance = instance ; instance . scope . on ( ) ; } ; export const unsetCurrentInstance = ( ) => { currentInstance && currentInstance . scope . off ( ) ; currentInstance = null ; } ; const isBuiltInTag = makeMap ( 'slot,component' ) ; export function validateComponentName ( name , config ) { const appIsNativeTag = config . isNativeTag || NO ; if ( isBuiltInTag ( name ) || appIsNativeTag ( name ) ) { warn ( 'Do not use built-in or reserved HTML elements as component id: ' + name ) ; } } export function isStatefulComponent ( instance ) { return instance . vnode . shapeFlag & ShapeFlags . STATEFUL_COMPONENT ; } export let isInSSRComponentSetup = false ; export function setupComponent ( instance , isSSR = false ) { isInSSRComponentSetup = isSSR ; const { props , children } = instance . vnode ; const isStateful = isStatefulComponent ( instance ) ; initProps ( instance , props , isStateful , isSSR ) ; initSlots ( instance , children ) ; const setupResult = isStateful ? setupStatefulComponent ( instance , isSSR ) : undefined ; isInSSRComponentSetup = false ; return setupResult ; } function setupStatefulComponent ( instance , isSSR ) { const Component = instance . type as ComponentOptions ; if ( __DEV__ ) { if ( Component . name ) { validateComponentName ( Component . name , instance . appContext . config ) ; } if ( Component . components ) { const names = Object . keys ( Component . components ) ; for ( let i = 0 ; i < names . length ; i ++ ) { validateComponentName ( names [ i ] , instance . appContext . config ) ; } } if ( Component . directives ) { const names = Object . keys ( Component . directives ) ; for ( let i = 0 ; i < names . length ; i ++ ) { validateDirectiveName ( names [ i ] ) ; } } if ( Component . compilerOptions && isRuntimeOnly ( ) ) { warn ( `"compilerOptions" is only supported when using a build of Vue that ` + `includes the runtime compiler. Since you are using a runtime-only ` + `build, the options should be passed via your build tool config instead.` ) ; } } instance . accessCache = Object . create ( null ) ; instance . proxy = markRaw ( new Proxy ( instance . ctx , PublicInstanceProxyHandlers ) ) ; if ( __DEV__ ) { exposePropsOnRenderContext ( instance ) ; } const { setup } = Component ; if ( setup ) { const setupContext = ( instance . setupContext = setup . length > 1 ? createSetupContext ( instance ) : null ) ; setCurrentInstance ( instance ) ; pauseTracking ( ) ; const setupResult = callWithErrorHandling ( setup , instance , ErrorCodes . SETUP_FUNCTION , [ __DEV__ ? shallowReadonly ( instance . props ) : instance . props , setupContext ] ) ; resetTracking ( ) ; unsetCurrentInstance ( ) ; if ( isPromise ( setupResult ) ) { setupResult . then ( unsetCurrentInstance , unsetCurrentInstance ) ; if ( isSSR ) { return setupResult . then ( ( resolvedResult ) => { handleSetupResult ( instance , resolvedResult , isSSR ) ; } ) . catch ( e => { handleError ( e , instance , ErrorCodes . SETUP_FUNCTION ) ; } ) ; } else if ( __FEATURE_SUSPENSE__ ) { instance . asyncDep = setupResult ; } else if ( __DEV__ ) { warn ( `setup() returned a Promise, but the version of Vue you are using ` + `does not support it yet.` ) ; } } else { handleSetupResult ( instance , setupResult , isSSR ) ; } } else { finishComponentSetup ( instance , isSSR ) ; } } export function handleSetupResult ( instance , setupResult , isSSR ) { if ( isFunction ( setupResult ) ) { if ( __NODE_JS__ && ( instance . type as ComponentOptions ) . __ssrInlineRender ) { instance . ssrRender = setupResult ; } else { instance . render = setupResult as InternalRenderFunction ; } } else if ( isObject ( setupResult ) ) { if ( __DEV__ && isVNode ( setupResult ) ) { warn ( `setup() should not return VNodes directly - ` + `return a render function instead.` ) ; } if ( __DEV__ || __FEATURE_PROD_DEVTOOLS__ ) { instance . devtoolsRawSetupState = setupResult ; } instance . setupState = proxyRefs ( setupResult ) ; if ( __DEV__ ) { exposeSetupStateOnRenderContext ( instance ) ; } } else if ( __DEV__ && setupResult !== undefined ) { warn ( `setup() should return an object. Received: ${ setupResult === null ? 'null' : typeof setupResult }` ) ; } finishComponentSetup ( instance , isSSR ) ; } type CompileFunction = ( template : string | object , options ? : CompilerOptions ) => InternalRenderFunction ; let compile ; let installWithProxy ; /**
 * For runtime-dom to register the compiler.
 * Note the exported method uses any to avoid d.ts relying on the compiler types.
 */ export function registerRuntimeCompiler ( _compile ) { compile = _compile ; installWithProxy = i => { if ( i . render ! . _rc ) { i . withProxy = new Proxy ( i . ctx , RuntimeCompiledPublicInstanceProxyHandlers ) ; } } ; } export const isRuntimeOnly = ( ) => ! compile ; export function finishComponentSetup ( instance , isSSR , skipOptions ? ) { const Component = instance . type as ComponentOptions ; if ( __COMPAT__ ) { convertLegacyRenderFn ( instance ) ; if ( __DEV__ && Component . compatConfig ) { validateCompatConfig ( Component . compatConfig ) ; } } if ( __NODE_JS__ && isSSR ) { instance . render = ( instance . render || Component . render || NOOP ) as InternalRenderFunction ; } else if ( ! instance . render ) { if ( compile && ! Component . render ) { const template = ( __COMPAT__ && instance . vnode . props && instance . vnode . props [ 'inline-template' ] ) || Component . template ; if ( template ) { if ( __DEV__ ) { startMeasure ( instance , `compile` ) ; } const { isCustomElement , compilerOptions } = instance . appContext . config ; const { delimiters , compilerOptions : componentCompilerOptions } = Component ; const finalCompilerOptions = extend ( extend ( { isCustomElement , delimiters } , compilerOptions ) , componentCompilerOptions ) ; if ( __COMPAT__ ) { finalCompilerOptions . compatConfig = Object . create ( globalCompatConfig ) ; if ( Component . compatConfig ) { extend ( finalCompilerOptions . compatConfig , Component . compatConfig ) ; } } Component . render = compile ( template , finalCompilerOptions ) ; if ( __DEV__ ) { endMeasure ( instance , `compile` ) ; } } } instance . render = ( Component . render || NOOP ) as InternalRenderFunction ; if ( installWithProxy ) { installWithProxy ( instance ) ; } } if ( __FEATURE_OPTIONS_API__ && ! ( __COMPAT__ && skipOptions ) ) { setCurrentInstance ( instance ) ; pauseTracking ( ) ; applyOptions ( instance ) ; resetTracking ( ) ; unsetCurrentInstance ( ) ; } if ( __DEV__ && ! Component . render && instance . render === NOOP && ! isSSR ) { if ( ! compile && Component . template ) { warn ( `Component provided template option but ` + `runtime compilation is not supported in this build of Vue.` + ( __ESM_BUNDLER__ ? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".` : __ESM_BROWSER__ ? ` Use "vue.esm-browser.js" instead.` : __GLOBAL__ ? ` Use "vue.global.js" instead.` : `` ) ) ; } else { warn ( `Component is missing template or render function.` ) ; } } } function createAttrsProxy ( instance ) { return new Proxy ( instance . attrs , __DEV__ ? { get ( target , key ) { markAttrsAccessed ( ) ; track ( instance , TrackOpTypes . GET , '$attrs' ) ; return target [ key ] ; } , set ( ) { warn ( `setupContext.attrs is readonly.` ) ; return false ; } , deleteProperty ( ) { warn ( `setupContext.attrs is readonly.` ) ; return false ; } } : { get ( target , key ) { track ( instance , TrackOpTypes . GET , '$attrs' ) ; return target [ key ] ; } } ) ; } export function createSetupContext ( instance ) { const expose = exposed => { if ( __DEV__ && instance . exposed ) { warn ( `expose() should be called only once per setup().` ) ; } instance . exposed = exposed || { } ; } ; let attrs ; if ( __DEV__ ) { return Object . freeze ( { get attrs ( ) { return attrs || ( attrs = createAttrsProxy ( instance ) ) ; } , get slots ( ) { return shallowReadonly ( instance . slots ) ; } , get emit ( ) { return ( event , ... args ) => instance . emit ( event , ... args ) ; } , expose } ) ; } else { return { get attrs ( ) { return attrs || ( attrs = createAttrsProxy ( instance ) ) ; } , slots : instance . slots , emit : instance . emit , expose } ; } } export function getExposeProxy ( instance ) { if ( instance . exposed ) { return ( instance . exposeProxy || ( instance . exposeProxy = new Proxy ( proxyRefs ( markRaw ( instance . exposed ) ) , { get ( target , key ) { if ( key in target ) { return target [ key ] ; } else if ( key in publicPropertiesMap ) { return publicPropertiesMap [ key ] ( instance ) ; } } } ) ) ) ; } } const classifyRE = /(?:^|[-_])(\w)/g ; const classify = ( str ) : string => str . replace ( classifyRE , c => c . toUpperCase ( ) ) . replace ( /[-_]/g , '' ) ; export function getComponentName ( Component ) { return isFunction ( Component ) ? Component . displayName || Component . name : Component . name ; } export function formatComponentName ( instance , Component , isRoot = false ) { let name = getComponentName ( Component ) ; if ( ! name && Component . __file ) { const match = Component . __file . match ( /([^/\\]+)\.\w+$/ ) ; if ( match ) { name = match [ 1 ] ; } } if ( ! name && instance && instance . parent ) { const inferFromRegistry = ( registry ) => { for ( const key in registry ) { if ( registry [ key ] === Component ) { return key ; } } } ; name = inferFromRegistry ( instance . components || ( instance . parent . type as ComponentOptions ) . components ) || inferFromRegistry ( instance . appContext . components ) ; } return name ? classify ( name ) : isRoot ? `App` : `Anonymous` ; } export function isClassComponent ( value ) { return isFunction ( value ) && '__vccOpts' in value ; }