fix(custom-elements): work with async component + slots (#4657)
close #4639
This commit is contained in:
		
							parent
							
								
									1612971471
								
							
						
					
					
						commit
						f4d2c9fc6a
					
				| @ -4,8 +4,9 @@ import { | ||||
|   ContextualRenderFn, | ||||
|   currentRenderingInstance | ||||
| } from '../componentRenderContext' | ||||
| import { Comment, isVNode } from '../vnode' | ||||
| import { | ||||
|   Comment, | ||||
|   isVNode, | ||||
|   VNodeArrayChildren, | ||||
|   openBlock, | ||||
|   createBlock, | ||||
| @ -15,6 +16,7 @@ import { | ||||
| import { PatchFlags, SlotFlags } from '@vue/shared' | ||||
| import { warn } from '../warning' | ||||
| import { createVNode } from '@vue/runtime-core' | ||||
| import { isAsyncWrapper } from '../apiAsyncComponent' | ||||
| 
 | ||||
| /** | ||||
|  * Compiler runtime helper for rendering `<slot/>` | ||||
| @ -29,7 +31,12 @@ export function renderSlot( | ||||
|   fallback?: () => VNodeArrayChildren, | ||||
|   noSlotted?: boolean | ||||
| ): VNode { | ||||
|   if (currentRenderingInstance!.isCE) { | ||||
|   if ( | ||||
|     currentRenderingInstance!.isCE || | ||||
|     (currentRenderingInstance!.parent && | ||||
|       isAsyncWrapper(currentRenderingInstance!.parent) && | ||||
|       currentRenderingInstance!.parent.isCE) | ||||
|   ) { | ||||
|     return createVNode( | ||||
|       'slot', | ||||
|       name === 'default' ? null : { name }, | ||||
|  | ||||
| @ -457,5 +457,33 @@ describe('defineCustomElement', () => { | ||||
|       const e = container.childNodes[0] as VueElement | ||||
|       expect(e.shadowRoot!.innerHTML).toBe(`<div>20,number</div>`) | ||||
|     }) | ||||
| 
 | ||||
|     test('with slots', async () => { | ||||
|       const E = defineCustomElement( | ||||
|         defineAsyncComponent(() => { | ||||
|           return Promise.resolve({ | ||||
|             render(this: any) { | ||||
|               return [ | ||||
|                 h('div', null, [ | ||||
|                   renderSlot(this.$slots, 'default', undefined, () => [ | ||||
|                     h('div', 'fallback') | ||||
|                   ]) | ||||
|                 ]), | ||||
|                 h('div', null, renderSlot(this.$slots, 'named')) | ||||
|               ] | ||||
|             } | ||||
|           }) | ||||
|         }) | ||||
|       ) | ||||
|       customElements.define('my-el-async-slots', E) | ||||
|       container.innerHTML = `<my-el-async-slots><span>hi</span></my-el-async-slots>` | ||||
| 
 | ||||
|       await new Promise(r => setTimeout(r)) | ||||
| 
 | ||||
|       const e = container.childNodes[0] as VueElement | ||||
|       expect(e.shadowRoot!.innerHTML).toBe( | ||||
|         `<div><slot><div>fallback</div></slot></div><div><slot name="named"></slot></div>` | ||||
|       ) | ||||
|     }) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user