8000 fix(runtime-core): filter single root for nested DEV_ROOT_FRAGMENT by edison1105 · Pull Request #8593 · vuejs/core · GitHub
[go: up one dir, main page]

Skip to content

fix(runtime-core): filter single root for nested DEV_ROOT_FRAGMENT #8593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 12, 2024
Merged
Prev Previous commit
Next Next commit
chore: add more case
  • Loading branch information
edison1105 committed Sep 14, 2023
commit 8a01c3e486157cee5c84604cf08bce0ae588dddd
53 changes: 53 additions & 0 deletions packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
withModifiers
} from '@vue/runtime-dom'
import { PatchFlags } from '@vue/shared'
import { createElementBlock, createElementVNode } from '../src'

describe('attribute fallthrough', () => {
it('should allow attrs to fallthrough', async () => {
Expand Down Expand Up @@ -673,6 +674,58 @@ describe('attribute fallthrough', () => {
expect(click).toHaveBeenCalled()
})

it('should support fallthrough for nested fragments', async () => {
const toggle = ref(false)

const Child = {
setup() {
return () => (
openBlock(),
createElementBlock(
Fragment,
null,
[
createCommentVNode(' comment A '),
toggle.value
? (openBlock(), createElementBlock('span', { key: 0 }, 'Foo'))
: (openBlock(),
createElementBlock(
Fragment,
{ key: 1 },
[
createCommentVNode(' comment B '),
createElementVNode('div', null, 'Bar')
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT
))
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT
)
)
}
}

const Root = {
setup() {
return () => (openBlock(), createBlock(Child, { class: 'red' }))
}
}

const root = document.createElement('div')
document.body.appendChild(root)
render(h(Root), root)

expect(root.innerHTML).toBe(
`<!-- comment A --><!-- comment B --><div class="red">Bar</div>`
)

toggle.value = true
await nextTick()
expect(root.innerHTML).toBe(
`<!-- comment A --><span class=\"red\">Foo</span>`
)
})

// #1989
it('should not fallthrough v-model listeners with corresponding declared prop', () => {
let textFoo = ''
Expand Down
12 changes: 10 additions & 2 deletions packages/runtime-core/src/componentRenderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,16 @@ export function renderComponentRoot(
const getChildRoot = (vnode: VNode): [VNode, SetRootFn] => {
const rawChildren = vnode.children as VNodeArrayChildren
const dynamicChildren = vnode.dynamicChildren
const childRoot = filterSingleRoot(rawChildren)
const childRoot = filterSingleRoot(rawChildren, false)
if (!childRoot) {
return [vnode, undefined]
} else if (
childRoot.patchFlag > 0 &&
childRoot.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT
) {
return getChildRoot(childRoot)
}

const index = rawChildren.indexOf(childRoot)
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1
const setRoot: SetRootFn = (updatedRoot: VNode) => {
Expand All @@ -271,7 +277,8 @@ const getChildRoot = (vnode: VNode): [VNode, SetRootFn] => {
}

export function filterSingleRoot(
children: VNodeArrayChildren
children: VNodeArrayChildren,
recursion: boolean = true
): VNode | undefined {
let singleRoot
for (let i = 0; i < children.length; i++) {
Expand All @@ -285,6 +292,7 @@ export function filterSingleRoot(
} else {
singleRoot = child
if (
recursion &&
singleRoot.patchFlag > 0 &&
singleRoot.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT
) {
Expand Down
0