refactor: fix implementation of SFC :slotted id handling

fix #2892
This commit is contained in:
Evan You
2021-03-05 11:10:06 -05:00
parent cc975c1292
commit aea88c3280
36 changed files with 723 additions and 457 deletions

View File

@@ -177,6 +177,7 @@ type PatchFn = (
parentComponent?: ComponentInternalInstance | null,
parentSuspense?: SuspenseBoundary | null,
isSVG?: boolean,
slotScopeIds?: string[] | null,
optimized?: boolean
) => void
@@ -187,6 +188,7 @@ type MountChildrenFn = (
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean,
start?: number
) => void
@@ -199,7 +201,8 @@ type PatchChildrenFn = (
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
optimized?: boolean
slotScopeIds: string[] | null,
optimized: boolean
) => void
type PatchBlockChildrenFn = (
@@ -208,7 +211,8 @@ type PatchBlockChildrenFn = (
fallbackContainer: RendererElement,
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean
isSVG: boolean,
slotScopeIds: string[] | null
) => void
type MoveFn = (
@@ -469,6 +473,7 @@ function baseCreateRenderer(
parentComponent = null,
parentSuspense = null,
isSVG = false,
slotScopeIds = null,
optimized = false
) => {
// patching & not same type, unmount old tree
@@ -507,6 +512,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
break
@@ -520,6 +526,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else if (shapeFlag & ShapeFlags.COMPONENT) {
@@ -531,6 +538,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else if (shapeFlag & ShapeFlags.TELEPORT) {
@@ -542,6 +550,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized,
internals
)
@@ -554,6 +563,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized,
internals
)
@@ -676,6 +686,7 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
isSVG = isSVG || (n2.type as string) === 'svg'
@@ -687,10 +698,19 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else {
patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized)
patchElement(
n1,
n2,
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
}
}
@@ -701,19 +721,12 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
let el: RendererElement
let vnodeHook: VNodeHook | undefined | null
const {
type,
props,
shapeFlag,
transition,
scopeId,
patchFlag,
dirs
} = vnode
const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode
if (
!__DEV__ &&
vnode.el &&
@@ -744,6 +757,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG && type !== 'foreignObject',
slotScopeIds,
optimized || !!vnode.dynamicChildren
)
}
@@ -773,7 +787,7 @@ function baseCreateRenderer(
}
}
// scopeId
setScopeId(el, scopeId, vnode, parentComponent)
setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent)
}
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
Object.defineProperty(el, '__vnode', {
@@ -813,30 +827,32 @@ function baseCreateRenderer(
const setScopeId = (
el: RendererElement,
scopeId: string | false | null,
vnode: VNode,
scopeId: string | null,
slotScopeIds: string[] | null,
parentComponent: ComponentInternalInstance | null
) => {
if (scopeId) {
hostSetScopeId(el, scopeId)
}
if (parentComponent) {
const treeOwnerId = parentComponent.type.__scopeId
// vnode's own scopeId and the current patched component's scopeId is
// different - this is a slot content node.
if (treeOwnerId && treeOwnerId !== scopeId) {
hostSetScopeId(el, treeOwnerId + '-s')
if (slotScopeIds) {
for (let i = 0; i < slotScopeIds.length; i++) {
hostSetScopeId(el, slotScopeIds[i])
}
}
if (parentComponent) {
let subTree = parentComponent.subTree
if (__DEV__ && subTree.type === Fragment) {
if (__DEV__ && subTree.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT) {
subTree =
filterSingleRoot(subTree.children as VNodeArrayChildren) || subTree
}
if (vnode === subTree) {
const parentVNode = parentComponent.vnode
setScopeId(
el,
parentComponent.vnode.scopeId,
parentComponent.vnode,
parentVNode,
parentVNode.scopeId,
parentVNode.slotScopeIds,
parentComponent.parent
)
}
@@ -851,6 +867,7 @@ function baseCreateRenderer(
parentSuspense,
isSVG,
optimized,
slotScopeIds,
start = 0
) => {
for (let i = start; i < children.length; i++) {
@@ -865,7 +882,8 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
optimized
optimized,
slotScopeIds
)
}
}
@@ -876,6 +894,7 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
const el = (n2.el = n1.el!)
@@ -993,7 +1012,8 @@ function baseCreateRenderer(
el,
parentComponent,
parentSuspense,
areChildrenSVG
areChildrenSVG,
slotScopeIds
)
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
traverseStaticChildren(n1, n2)
@@ -1007,7 +1027,9 @@ function baseCreateRenderer(
null,
parentComponent,
parentSuspense,
areChildrenSVG
areChildrenSVG,
slotScopeIds,
false
)
}
@@ -1026,7 +1048,8 @@ function baseCreateRenderer(
fallbackContainer,
parentComponent,
parentSuspense,
isSVG
isSVG,
slotScopeIds
) => {
for (let i = 0; i < newChildren.length; i++) {
const oldVNode = oldChildren[i]
@@ -1054,6 +1077,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
true
)
}
@@ -1119,16 +1143,24 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''))!
const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''))!
let { patchFlag, dynamicChildren } = n2
let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2
if (patchFlag > 0) {
optimized = true
}
// check if this is a slot fragment with :slotted scope ids
if (fragmentSlotScopeIds) {
slotScopeIds = slotScopeIds
? slotScopeIds.concat(fragmentSlotScopeIds)
: fragmentSlotScopeIds
}
if (__DEV__ && isHmrUpdating) {
// HMR updated, force full diff
patchFlag = 0
@@ -1149,6 +1181,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else {
@@ -1168,7 +1201,8 @@ function baseCreateRenderer(
container,
parentComponent,
parentSuspense,
isSVG
isSVG,
slotScopeIds
)
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
traverseStaticChildren(n1, n2)
@@ -1195,6 +1229,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
}
@@ -1209,8 +1244,10 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
n2.slotScopeIds = slotScopeIds
if (n1 == null) {
if (n2.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) {
;(parentComponent!.ctx as KeepAliveContext).activate(
@@ -1382,7 +1419,8 @@ function baseCreateRenderer(
initialVNode.el as Node,
subTree,
instance,
parentSuspense
parentSuspense,
null
)
if (__DEV__) {
endMeasure(instance, `hydrate`)
@@ -1543,6 +1581,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized = false
) => {
const c1 = n1 && n1.children
@@ -1563,6 +1602,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
return
@@ -1576,6 +1616,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
return
@@ -1604,6 +1645,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else {
@@ -1625,6 +1667,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
}
@@ -1640,6 +1683,7 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
c1 = c1 || EMPTY_ARR
@@ -1660,6 +1704,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
}
@@ -1682,6 +1727,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized,
commonLength
)
@@ -1697,6 +1743,7 @@ function baseCreateRenderer(
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
slotScopeIds: string[] | null,
optimized: boolean
) => {
let i = 0
@@ -1721,6 +1768,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else {
@@ -1746,6 +1794,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
} else {
@@ -1776,7 +1825,9 @@ function baseCreateRenderer(
anchor,
parentComponent,
parentSuspense,
isSVG
isSVG,
slotScopeIds,
optimized
)
i++
}
@@ -1878,6 +1929,7 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
slotScopeIds,
optimized
)
patched++
@@ -1905,7 +1957,9 @@ function baseCreateRenderer(
anchor,
parentComponent,
parentSuspense,
isSVG
isSVG,
slotScopeIds,
optimized
)
} else if (moved) {
// move if: