block = []
}
instance.block = block
- fallThroughAttrs(instance)
- attachScopeId(instance)
+
+ const rootElement = findFirstRootElement(instance)
+ if (rootElement) {
+ fallThroughAttrs(instance, rootElement)
+
+ // attach scopeId
+ for (const id of instance.scopeIds) {
+ rootElement.setAttribute(id, '')
+ }
+ }
+
return block
})
reset()
flushPostFlushCbs()
}
-export function attachScopeId(instance: ComponentInternalInstance): void {
- const scopeId = instance.type.__scopeId
- if (scopeId) {
- let blk: Block | null = instance.block
- while (blk && componentKey in blk) {
- blk = blk.block
- if (blk instanceof Element) {
- blk.setAttribute(scopeId, '')
- }
+function findFirstRootElement(instance: ComponentInternalInstance) {
+ const element = getFirstNode(instance.block)
+ return element instanceof Element ? element : undefined
+}
+
+function getFirstNode(block: Block | null): Node | undefined {
+ if (!block || componentKey in block) return
+ if (block instanceof Node) return block
+ if (isArray(block)) {
+ if (block.length === 1) {
+ return getFirstNode(block[0])
}
+ } else {
+ return getFirstNode(block.nodes)
}
}
provides: Data
scope: EffectScope
comps: Set<ComponentInternalInstance>
+ scopeIds: string[]
rawProps: NormalizedRawProps
propsOptions: NormalizedPropsOptions
provides: parent ? parent.provides : Object.create(_appContext.provides),
type: component,
comps: new Set(),
+ scopeIds: [],
// resolved props and emits options
rawProps: null!, // set later
import { camelize, isArray, normalizeClass, normalizeStyle } from '@vue/shared'
-import {
- type ComponentInternalInstance,
- componentKey,
- currentInstance,
-} from './component'
+import { type ComponentInternalInstance, currentInstance } from './component'
import { isEmitListener } from './componentEmits'
import { type RawProps, walkRawProps } from './componentProps'
import { renderEffect } from './renderEffect'
import { mergeProp, setDynamicProp } from './dom/prop'
-import type { Block } from './apiRender'
export function patchAttrs(
instance: ComponentInternalInstance,
return [attrsGetter, props]
}
-function getFirstNode(block: Block | undefined): Node | undefined {
- if (!block || componentKey in block) return
- if (block instanceof Node) return block
- if (isArray(block)) {
- if (block.length === 1) {
- return getFirstNode(block[0])
- }
- } else {
- return getFirstNode(block.nodes)
- }
-}
-
-export function fallThroughAttrs(instance: ComponentInternalInstance): void {
+export function fallThroughAttrs(
+ instance: ComponentInternalInstance,
+ element: Element,
+): void {
const {
- block,
type: { inheritAttrs },
dynamicAttrs,
} = instance
if (
inheritAttrs === false ||
- dynamicAttrs === true || // all props as dynamic
- !block ||
- componentKey in block
+ dynamicAttrs === true // all props as dynamic
)
return
- const element = getFirstNode(block)
- if (!element || !(element instanceof Element)) return
-
const hasStaticAttrs = dynamicAttrs || dynamicAttrs === false
let initial: Record<string, string> | undefined