Skip to content

Commit 1af3531

Browse files
committed
fix(runtime-core): fix attr fallthrough on compiled framgent w/ single static element + comments
1 parent 6390ddf commit 1af3531

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
openBlock,
1111
createBlock,
1212
FunctionalComponent,
13-
createCommentVNode
13+
createCommentVNode,
14+
Fragment
1415
} from '@vue/runtime-dom'
1516
import { mockWarn } from '@vue/shared'
1617

@@ -573,12 +574,15 @@ describe('attribute fallthrough', () => {
573574
}
574575

575576
const Child = {
576-
setup(props: any) {
577-
return () => [
578-
createCommentVNode('hello'),
579-
h('button'),
580-
createCommentVNode('world')
581-
]
577+
setup() {
578+
return () => (
579+
openBlock(),
580+
createBlock(Fragment, null, [
581+
createCommentVNode('hello'),
582+
h('button'),
583+
createCommentVNode('world')
584+
])
585+
)
582586
}
583587
}
584588

packages/runtime-core/src/componentRenderUtils.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ export function renderComponentRoot(
215215
return result
216216
}
217217

218+
/**
219+
* dev only
220+
*/
218221
const getChildRoot = (
219222
vnode: VNode
220223
): [VNode, ((root: VNode) => void) | undefined] => {
@@ -231,12 +234,14 @@ const getChildRoot = (
231234
}
232235
const childRoot = children[0]
233236
const index = rawChildren.indexOf(childRoot)
234-
const dynamicIndex = dynamicChildren
235-
? dynamicChildren.indexOf(childRoot)
236-
: null
237+
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1
237238
const setRoot = (updatedRoot: VNode) => {
238239
rawChildren[index] = updatedRoot
239-
if (dynamicIndex !== null) dynamicChildren[dynamicIndex] = updatedRoot
240+
if (dynamicIndex > -1) {
241+
dynamicChildren[dynamicIndex] = updatedRoot
242+
} else if (dynamicChildren && updatedRoot.patchFlag > 0) {
243+
dynamicChildren.push(updatedRoot)
244+
}
240245
}
241246
return [normalizeVNode(childRoot), setRoot]
242247
}

packages/runtime-core/src/vnode.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -426,19 +426,20 @@ export function cloneVNode<T, U>(
426426
vnode: VNode<T, U>,
427427
extraProps?: Data & VNodeProps | null
428428
): VNode<T, U> {
429-
const props = extraProps
430-
? vnode.props
431-
? mergeProps(vnode.props, extraProps)
432-
: extend({}, extraProps)
433-
: vnode.props
434429
// This is intentionally NOT using spread or extend to avoid the runtime
435430
// key enumeration cost.
431+
const { props, patchFlag } = vnode
432+
const mergedProps = extraProps
433+
? props
434+
? mergeProps(props, extraProps)
435+
: extend({}, extraProps)
436+
: props
436437
return {
437438
__v_isVNode: true,
438439
__v_skip: true,
439440
type: vnode.type,
440-
props,
441-
key: props && normalizeKey(props),
441+
props: mergedProps,
442+
key: mergedProps && normalizeKey(mergedProps),
442443
ref: extraProps && extraProps.ref ? normalizeRef(extraProps) : vnode.ref,
443444
scopeId: vnode.scopeId,
444445
children: vnode.children,
@@ -448,10 +449,14 @@ export function cloneVNode<T, U>(
448449
shapeFlag: vnode.shapeFlag,
449450
// if the vnode is cloned with extra props, we can no longer assume its
450451
// existing patch flag to be reliable and need to add the FULL_PROPS flag.
452+
// note: perserve flag for fragments since they use the flag for children
453+
// fast paths only.
451454
patchFlag:
452455
extraProps && vnode.type !== Fragment
453-
? vnode.patchFlag | PatchFlags.FULL_PROPS
454-
: vnode.patchFlag,
456+
? patchFlag === -1 // hoisted node
457+
? PatchFlags.FULL_PROPS
458+
: patchFlag | PatchFlags.FULL_PROPS
459+
: patchFlag,
455460
dynamicProps: vnode.dynamicProps,
456461
dynamicChildren: vnode.dynamicChildren,
457462
appContext: vnode.appContext,

0 commit comments

Comments
 (0)