Просмотр исходного кода

fix(custom-element): update slot nodes when shadowRoot is false

daiwei 1 год назад
Родитель
Сommit
8e5a43842b

+ 1 - 0
packages/runtime-core/src/helpers/renderSlot.ts

@@ -96,6 +96,7 @@ export function renderSlot(
   if (slot && (slot as ContextualRenderFn)._c) {
     ;(slot as ContextualRenderFn)._d = true
   }
+  rendered.slotName = name
   return rendered
 }
 

+ 4 - 0
packages/runtime-core/src/renderer.ts

@@ -934,6 +934,10 @@ function baseCreateRenderer(
         dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')
       }, parentSuspense)
     }
+
+    if (el._isVueCE && !el._def.shadowRoot) {
+      el._updateSlots(n2.children)
+    }
   }
 
   // The fast path for blocks.

+ 5 - 0
packages/runtime-core/src/vnode.ts

@@ -253,6 +253,10 @@ export interface VNode<
    * @internal custom element interception hook
    */
   ce?: (instance: ComponentInternalInstance) => void
+  /**
+   * @internal
+   */
+  slotName?: string
 }
 
 // Since v-if and v-for are the two possible ways node structure can dynamically
@@ -715,6 +719,7 @@ export function cloneVNode<T, U>(
     anchor: vnode.anchor,
     ctx: vnode.ctx,
     ce: vnode.ce,
+    slotName: vnode.slotName,
   }
 
   // if the vnode will be replaced by the cloned one, it is necessary

+ 30 - 0
packages/runtime-dom/src/apiCustomElement.ts

@@ -19,15 +19,18 @@ import {
   type EmitsOptions,
   type EmitsToProps,
   type ExtractPropTypes,
+  Fragment,
   type MethodOptions,
   type RenderFunction,
   type SetupContext,
   type SlotsType,
   type VNode,
+  type VNodeArrayChildren,
   type VNodeProps,
   createVNode,
   defineComponent,
   getCurrentInstance,
+  isVNode,
   nextTick,
   unref,
   warn,
@@ -657,6 +660,17 @@ export class VueElement
     }
   }
 
+  /**
+   * @internal
+   */
+  _updateSlots(children: VNode[]): void {
+    children.forEach(child => {
+      this._slots![child.slotName!] = collectElements(
+        child.children as VNodeArrayChildren,
+      )
+    })
+  }
+
   /**
    * @internal
    */
@@ -710,3 +724,19 @@ export function useShadowRoot(): ShadowRoot | null {
   const el = __DEV__ ? useHost('useShadowRoot') : useHost()
   return el && el.shadowRoot
 }
+
+function collectElements(children: VNodeArrayChildren): Node[] {
+  const nodes: Node[] = []
+  for (const vnode of children) {
+    if (isArray(vnode)) {
+      nodes.push(...collectElements(vnode))
+    } else if (isVNode(vnode)) {
+      if (vnode.type === Fragment) {
+        nodes.push(...collectElements(vnode.children as VNodeArrayChildren))
+      } else if (vnode.el) {
+        nodes.push(vnode.el as Node)
+      }
+    }
+  }
+  return nodes
+}