mirror of https://github.com/vuejs/core.git
fix(runtime-core): use separate prop caches for components and mixins (#11350)
Co-authored-by: Red Huang <gcaaa31928@gmail.com> close #7998
This commit is contained in:
parent
c8b9794575
commit
b0aa234e5e
|
@ -538,6 +538,96 @@ describe('component props', () => {
|
||||||
expect(renderProxy.$props).toMatchObject(props)
|
expect(renderProxy.$props).toMatchObject(props)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('merging props from global mixins and extends', () => {
|
||||||
|
let renderProxy: any
|
||||||
|
let extendedRenderProxy: any
|
||||||
|
|
||||||
|
const defaultProp = ' from global'
|
||||||
|
const props = {
|
||||||
|
globalProp: {
|
||||||
|
type: String,
|
||||||
|
default: defaultProp,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const globalMixin = {
|
||||||
|
props,
|
||||||
|
}
|
||||||
|
const Comp = {
|
||||||
|
render(this: any) {
|
||||||
|
renderProxy = this
|
||||||
|
return h('div', ['Comp', this.globalProp])
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const ExtendedComp = {
|
||||||
|
extends: Comp,
|
||||||
|
render(this: any) {
|
||||||
|
extendedRenderProxy = this
|
||||||
|
return h('div', ['ExtendedComp', this.globalProp])
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = createApp(
|
||||||
|
{
|
||||||
|
render: () => [h(ExtendedComp), h(Comp)],
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
app.mixin(globalMixin)
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
app.mount(root)
|
||||||
|
|
||||||
|
expect(serializeInner(root)).toMatch(
|
||||||
|
`<div>ExtendedComp from global</div><div>Comp from global</div>`,
|
||||||
|
)
|
||||||
|
expect(renderProxy.$props).toMatchObject({ globalProp: defaultProp })
|
||||||
|
expect(extendedRenderProxy.$props).toMatchObject({
|
||||||
|
globalProp: defaultProp,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('merging props for a component that is also used as a mixin', () => {
|
||||||
|
const CompA = {
|
||||||
|
render(this: any) {
|
||||||
|
return this.foo
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const mixin = {
|
||||||
|
props: {
|
||||||
|
foo: {
|
||||||
|
default: 'from mixin',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const CompB = {
|
||||||
|
mixins: [mixin, CompA],
|
||||||
|
render(this: any) {
|
||||||
|
return this.foo
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
render() {
|
||||||
|
return [h(CompA), ', ', h(CompB)]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mixin({
|
||||||
|
props: {
|
||||||
|
foo: {
|
||||||
|
default: 'from global mixin',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
app.mount(root)
|
||||||
|
|
||||||
|
expect(serializeInner(root)).toMatch(`from global mixin, from mixin`)
|
||||||
|
})
|
||||||
|
|
||||||
test('props type support BigInt', () => {
|
test('props type support BigInt', () => {
|
||||||
const Comp = {
|
const Comp = {
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -496,12 +496,15 @@ function resolvePropValue(
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mixinPropsCache = new WeakMap<ConcreteComponent, NormalizedPropsOptions>()
|
||||||
|
|
||||||
export function normalizePropsOptions(
|
export function normalizePropsOptions(
|
||||||
comp: ConcreteComponent,
|
comp: ConcreteComponent,
|
||||||
appContext: AppContext,
|
appContext: AppContext,
|
||||||
asMixin = false,
|
asMixin = false,
|
||||||
): NormalizedPropsOptions {
|
): NormalizedPropsOptions {
|
||||||
const cache = appContext.propsCache
|
const cache =
|
||||||
|
__FEATURE_OPTIONS_API__ && asMixin ? mixinPropsCache : appContext.propsCache
|
||||||
const cached = cache.get(comp)
|
const cached = cache.get(comp)
|
||||||
if (cached) {
|
if (cached) {
|
||||||
return cached
|
return cached
|
||||||
|
|
Loading…
Reference in New Issue