fix(runtime-core): fix resolving assets from mixins and extends

fix #1963
This commit is contained in:
Evan You
2020-08-26 18:09:54 -04:00
parent bc64c60c7e
commit 0cb7f7f880
4 changed files with 107 additions and 3 deletions

View File

@@ -24,7 +24,7 @@ import { Slots, initSlots, InternalSlots } from './componentSlots'
import { warn } from './warning'
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
import { validateDirectiveName } from './directives'
import { Directive, validateDirectiveName } from './directives'
import { applyOptions, ComponentOptions } from './componentOptions'
import {
EmitsOptions,
@@ -221,6 +221,17 @@ export interface ComponentInternalInstance {
*/
renderCache: (Function | VNode)[]
/**
* Resolved component registry, only for components with mixins or extends
* @internal
*/
components: Record<string, ConcreteComponent> | null
/**
* Resolved directive registry, only for components with mixins or extends
* @internal
*/
directives: Record<string, Directive> | null
// the rest are only for stateful components ---------------------------------
/**
@@ -372,6 +383,10 @@ export function createComponentInstance(
accessCache: null!,
renderCache: [],
// local resovled assets
components: null,
directives: null,
// state
ctx: EMPTY_OBJ,
data: EMPTY_OBJ,
@@ -733,7 +748,8 @@ export function formatComponentName(
}
name =
inferFromRegistry(
(instance.parent.type as ComponentOptions).components
instance.components ||
(instance.parent.type as ComponentOptions).components
) || inferFromRegistry(instance.appContext.components)
}

View File

@@ -384,6 +384,9 @@ export function applyOptions(
watch: watchOptions,
provide: provideOptions,
inject: injectOptions,
// assets
components,
directives,
// lifecycle
beforeMount,
mounted,
@@ -568,6 +571,32 @@ export function applyOptions(
}
}
// asset options.
// To reduce memory usage, only components with mixins or extends will have
// resolved asset registry attached to instance.
if (asMixin) {
if (components) {
extend(
instance.components ||
(instance.components = extend(
{},
(instance.type as ComponentOptions).components
) as Record<string, ConcreteComponent>),
components
)
}
if (directives) {
extend(
instance.directives ||
(instance.directives = extend(
{},
(instance.type as ComponentOptions).directives
)),
directives
)
}
}
// lifecycle options
if (!asMixin) {
callSyncHook('created', options, publicThis, globalMixins)

View File

@@ -83,7 +83,8 @@ function resolveAsset(
const res =
// local registration
resolve((Component as ComponentOptions)[type], name) ||
// check instance[type] first for components with mixin or extends.
resolve(instance[type] || (Component as ComponentOptions)[type], name) ||
// global registration
resolve(instance.appContext[type], name)
if (__DEV__ && warnMissing && !res) {