mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
fix: fix scopedSlots regression
This commit is contained in:
parent
642e7aa03b
commit
4f2a04e6a8
@ -102,7 +102,8 @@ export function renderMixin(Vue: typeof Component) {
|
||||
vm.$scopedSlots = normalizeScopedSlots(
|
||||
vm.$parent!,
|
||||
_parentVnode.data!.scopedSlots,
|
||||
vm.$slots
|
||||
vm.$slots,
|
||||
vm.$scopedSlots
|
||||
)
|
||||
if (vm._slotsProxy) {
|
||||
syncSetupSlots(vm._slotsProxy, vm.$scopedSlots)
|
||||
|
@ -8,35 +8,40 @@ import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
|
||||
|
||||
export function normalizeScopedSlots(
|
||||
ownerVm: Component,
|
||||
slots: { [key: string]: Function } | void,
|
||||
normalSlots: { [key: string]: VNode[] }
|
||||
scopedSlots: { [key: string]: Function } | undefined,
|
||||
normalSlots: { [key: string]: VNode[] },
|
||||
prevScopedSlots?: { [key: string]: Function }
|
||||
): any {
|
||||
let res
|
||||
const prevSlots = ownerVm.$scopedSlots
|
||||
const hasNormalSlots = Object.keys(normalSlots).length > 0
|
||||
const isStable = slots ? !!slots.$stable : !hasNormalSlots
|
||||
const key = slots && slots.$key
|
||||
if (!slots) {
|
||||
const isStable = scopedSlots ? !!scopedSlots.$stable : !hasNormalSlots
|
||||
const key = scopedSlots && scopedSlots.$key
|
||||
if (!scopedSlots) {
|
||||
res = {}
|
||||
} else if (slots._normalized) {
|
||||
} else if (scopedSlots._normalized) {
|
||||
// fast path 1: child component re-render only, parent did not change
|
||||
return slots._normalized
|
||||
return scopedSlots._normalized
|
||||
} else if (
|
||||
isStable &&
|
||||
prevSlots &&
|
||||
prevSlots !== emptyObject &&
|
||||
key === prevSlots.$key &&
|
||||
prevScopedSlots &&
|
||||
prevScopedSlots !== emptyObject &&
|
||||
key === prevScopedSlots.$key &&
|
||||
!hasNormalSlots &&
|
||||
!prevSlots.$hasNormal
|
||||
!prevScopedSlots.$hasNormal
|
||||
) {
|
||||
// fast path 2: stable scoped slots w/ no normal slots to proxy,
|
||||
// only need to normalize once
|
||||
return prevSlots
|
||||
return prevScopedSlots
|
||||
} else {
|
||||
res = {}
|
||||
for (const key in slots) {
|
||||
if (slots[key] && key[0] !== '$') {
|
||||
res[key] = normalizeScopedSlot(ownerVm, normalSlots, key, slots[key])
|
||||
for (const key in scopedSlots) {
|
||||
if (scopedSlots[key] && key[0] !== '$') {
|
||||
res[key] = normalizeScopedSlot(
|
||||
ownerVm,
|
||||
normalSlots,
|
||||
key,
|
||||
scopedSlots[key]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,8 +53,8 @@ export function normalizeScopedSlots(
|
||||
}
|
||||
// avoriaz seems to mock a non-extensible $scopedSlots object
|
||||
// and when that is passed down this would cause an error
|
||||
if (slots && Object.isExtensible(slots)) {
|
||||
slots._normalized = res
|
||||
if (scopedSlots && Object.isExtensible(scopedSlots)) {
|
||||
scopedSlots._normalized = res
|
||||
}
|
||||
def(res, '$stable', isStable)
|
||||
def(res, '$key', key)
|
||||
|
@ -1044,4 +1044,33 @@ describe('Component slot', () => {
|
||||
|
||||
expect(vm.$el.innerHTML).toBe(`<!----><span>b</span>`)
|
||||
})
|
||||
|
||||
// regression 2.7.0-alpha.4
|
||||
it('passing scoped slots through nested parent chain', () => {
|
||||
const Foo = {
|
||||
template: `
|
||||
<div><slot>foo default</slot></div>
|
||||
`
|
||||
}
|
||||
|
||||
const Bar = {
|
||||
components: { Foo },
|
||||
template: `<Foo><slot name="bar"/></Foo>`
|
||||
}
|
||||
|
||||
const App = {
|
||||
components: { Bar },
|
||||
template: `<Bar>
|
||||
<template #bar>
|
||||
<span>App content for Bar#bar</span>
|
||||
</template>
|
||||
</Bar>`
|
||||
}
|
||||
|
||||
const vm = new Vue({
|
||||
render: h => h(App)
|
||||
}).$mount()
|
||||
|
||||
expect(vm.$el.innerHTML).toMatch(`App content for Bar#bar`)
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user