mirror of https://github.com/vuejs/core.git
fix(custom-element): use PatchFlags.BAIL for slot when props are present (#13907)
close #13904
This commit is contained in:
parent
836b82976f
commit
5358bca4a8
|
@ -37,6 +37,7 @@ export function renderSlot(
|
||||||
isAsyncWrapper(currentRenderingInstance!.parent) &&
|
isAsyncWrapper(currentRenderingInstance!.parent) &&
|
||||||
currentRenderingInstance!.parent.ce)
|
currentRenderingInstance!.parent.ce)
|
||||||
) {
|
) {
|
||||||
|
const hasProps = Object.keys(props).length > 0
|
||||||
// in custom element mode, render <slot/> as actual slot outlets
|
// in custom element mode, render <slot/> as actual slot outlets
|
||||||
// wrap it with a fragment because in shadowRoot: false mode the slot
|
// wrap it with a fragment because in shadowRoot: false mode the slot
|
||||||
// element gets replaced by injected content
|
// element gets replaced by injected content
|
||||||
|
@ -47,7 +48,7 @@ export function renderSlot(
|
||||||
Fragment,
|
Fragment,
|
||||||
null,
|
null,
|
||||||
[createVNode('slot', props, fallback && fallback())],
|
[createVNode('slot', props, fallback && fallback())],
|
||||||
PatchFlags.STABLE_FRAGMENT,
|
hasProps ? PatchFlags.BAIL : PatchFlags.STABLE_FRAGMENT,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -638,6 +638,33 @@ describe('defineCustomElement', () => {
|
||||||
`<div><slot><div>fallback</div></slot></div><div><slot name="named"></slot></div>`,
|
`<div><slot><div>fallback</div></slot></div><div><slot name="named"></slot></div>`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('render slot props', async () => {
|
||||||
|
const foo = ref('foo')
|
||||||
|
const E = defineCustomElement({
|
||||||
|
render() {
|
||||||
|
return [
|
||||||
|
h(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
renderSlot(this.$slots, 'default', { class: foo.value }),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
customElements.define('my-el-slot-props', E)
|
||||||
|
container.innerHTML = `<my-el-slot-props><span>hi</span></my-el-slot-props>`
|
||||||
|
const e = container.childNodes[0] as VueElement
|
||||||
|
expect(e.shadowRoot!.innerHTML).toBe(
|
||||||
|
`<div><slot class="foo"></slot></div>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
foo.value = 'bar'
|
||||||
|
await nextTick()
|
||||||
|
expect(e.shadowRoot!.innerHTML).toBe(
|
||||||
|
`<div><slot class="bar"></slot></div>`,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('provide/inject', () => {
|
describe('provide/inject', () => {
|
||||||
|
|
Loading…
Reference in New Issue