fix(runtime-core): fix resolving assets from mixins and extends
fix #1963
This commit is contained in:
parent
bc64c60c7e
commit
0cb7f7f880
@ -151,4 +151,62 @@ describe('resolveAssets', () => {
|
|||||||
expect(serializeInner(root)).toBe('<div>hello</div>')
|
expect(serializeInner(root)).toBe('<div>hello</div>')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('resolving from mixins & extends', () => {
|
||||||
|
const FooBar = () => null
|
||||||
|
const BarBaz = { mounted: () => null }
|
||||||
|
|
||||||
|
let component1: Component | string
|
||||||
|
let component2: Component | string
|
||||||
|
let component3: Component | string
|
||||||
|
let component4: Component | string
|
||||||
|
let directive1: Directive
|
||||||
|
let directive2: Directive
|
||||||
|
let directive3: Directive
|
||||||
|
let directive4: Directive
|
||||||
|
|
||||||
|
const Base = {
|
||||||
|
components: {
|
||||||
|
FooBar: FooBar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Mixin = {
|
||||||
|
directives: {
|
||||||
|
BarBaz: BarBaz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Root = {
|
||||||
|
extends: Base,
|
||||||
|
mixins: [Mixin],
|
||||||
|
setup() {
|
||||||
|
return () => {
|
||||||
|
component1 = resolveComponent('FooBar')!
|
||||||
|
directive1 = resolveDirective('BarBaz')!
|
||||||
|
// camelize
|
||||||
|
component2 = resolveComponent('Foo-bar')!
|
||||||
|
directive2 = resolveDirective('Bar-baz')!
|
||||||
|
// capitalize
|
||||||
|
component3 = resolveComponent('fooBar')!
|
||||||
|
directive3 = resolveDirective('barBaz')!
|
||||||
|
// camelize and capitalize
|
||||||
|
component4 = resolveComponent('foo-bar')!
|
||||||
|
directive4 = resolveDirective('bar-baz')!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = createApp(Root)
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
app.mount(root)
|
||||||
|
expect(component1!).toBe(FooBar)
|
||||||
|
expect(component2!).toBe(FooBar)
|
||||||
|
expect(component3!).toBe(FooBar)
|
||||||
|
expect(component4!).toBe(FooBar)
|
||||||
|
|
||||||
|
expect(directive1!).toBe(BarBaz)
|
||||||
|
expect(directive2!).toBe(BarBaz)
|
||||||
|
expect(directive3!).toBe(BarBaz)
|
||||||
|
expect(directive4!).toBe(BarBaz)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -24,7 +24,7 @@ import { Slots, initSlots, InternalSlots } from './componentSlots'
|
|||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
|
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
|
||||||
import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
|
import { AppContext, createAppContext, AppConfig } from './apiCreateApp'
|
||||||
import { validateDirectiveName } from './directives'
|
import { Directive, validateDirectiveName } from './directives'
|
||||||
import { applyOptions, ComponentOptions } from './componentOptions'
|
import { applyOptions, ComponentOptions } from './componentOptions'
|
||||||
import {
|
import {
|
||||||
EmitsOptions,
|
EmitsOptions,
|
||||||
@ -221,6 +221,17 @@ export interface ComponentInternalInstance {
|
|||||||
*/
|
*/
|
||||||
renderCache: (Function | VNode)[]
|
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 ---------------------------------
|
// the rest are only for stateful components ---------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -372,6 +383,10 @@ export function createComponentInstance(
|
|||||||
accessCache: null!,
|
accessCache: null!,
|
||||||
renderCache: [],
|
renderCache: [],
|
||||||
|
|
||||||
|
// local resovled assets
|
||||||
|
components: null,
|
||||||
|
directives: null,
|
||||||
|
|
||||||
// state
|
// state
|
||||||
ctx: EMPTY_OBJ,
|
ctx: EMPTY_OBJ,
|
||||||
data: EMPTY_OBJ,
|
data: EMPTY_OBJ,
|
||||||
@ -733,7 +748,8 @@ export function formatComponentName(
|
|||||||
}
|
}
|
||||||
name =
|
name =
|
||||||
inferFromRegistry(
|
inferFromRegistry(
|
||||||
(instance.parent.type as ComponentOptions).components
|
instance.components ||
|
||||||
|
(instance.parent.type as ComponentOptions).components
|
||||||
) || inferFromRegistry(instance.appContext.components)
|
) || inferFromRegistry(instance.appContext.components)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +384,9 @@ export function applyOptions(
|
|||||||
watch: watchOptions,
|
watch: watchOptions,
|
||||||
provide: provideOptions,
|
provide: provideOptions,
|
||||||
inject: injectOptions,
|
inject: injectOptions,
|
||||||
|
// assets
|
||||||
|
components,
|
||||||
|
directives,
|
||||||
// lifecycle
|
// lifecycle
|
||||||
beforeMount,
|
beforeMount,
|
||||||
mounted,
|
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
|
// lifecycle options
|
||||||
if (!asMixin) {
|
if (!asMixin) {
|
||||||
callSyncHook('created', options, publicThis, globalMixins)
|
callSyncHook('created', options, publicThis, globalMixins)
|
||||||
|
@ -83,7 +83,8 @@ function resolveAsset(
|
|||||||
|
|
||||||
const res =
|
const res =
|
||||||
// local registration
|
// 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
|
// global registration
|
||||||
resolve(instance.appContext[type], name)
|
resolve(instance.appContext[type], name)
|
||||||
if (__DEV__ && warnMissing && !res) {
|
if (__DEV__ && warnMissing && !res) {
|
||||||
|
Loading…
Reference in New Issue
Block a user