fix: inherit el
for static nodes inside keyed template
fragment (#2089)
fix #2080
This commit is contained in:
parent
612eb6712a
commit
a32870a8f6
@ -10,9 +10,13 @@ import {
|
|||||||
dumpOps,
|
dumpOps,
|
||||||
NodeOpTypes,
|
NodeOpTypes,
|
||||||
serializeInner,
|
serializeInner,
|
||||||
createTextVNode
|
createTextVNode,
|
||||||
|
createBlock,
|
||||||
|
openBlock,
|
||||||
|
createCommentVNode
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import { PatchFlags } from '@vue/shared'
|
import { PatchFlags } from '@vue/shared'
|
||||||
|
import { renderList } from '../src/helpers/renderList'
|
||||||
|
|
||||||
describe('renderer: fragment', () => {
|
describe('renderer: fragment', () => {
|
||||||
it('should allow returning multiple component root nodes', () => {
|
it('should allow returning multiple component root nodes', () => {
|
||||||
@ -269,4 +273,46 @@ describe('renderer: fragment', () => {
|
|||||||
render(null, root)
|
render(null, root)
|
||||||
expect(serializeInner(root)).toBe(``)
|
expect(serializeInner(root)).toBe(``)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #2080
|
||||||
|
test('`template` keyed fragment w/ comment + hoisted node', () => {
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
const hoisted = h('span')
|
||||||
|
|
||||||
|
const renderFn = (items: string[]) => {
|
||||||
|
return (
|
||||||
|
openBlock(true),
|
||||||
|
createBlock(
|
||||||
|
Fragment,
|
||||||
|
null,
|
||||||
|
renderList(items, item => {
|
||||||
|
return (
|
||||||
|
openBlock(),
|
||||||
|
createBlock(
|
||||||
|
Fragment,
|
||||||
|
{ key: item },
|
||||||
|
[
|
||||||
|
createCommentVNode('comment'),
|
||||||
|
hoisted,
|
||||||
|
createVNode('div', null, item, PatchFlags.TEXT)
|
||||||
|
],
|
||||||
|
PatchFlags.STABLE_FRAGMENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
PatchFlags.KEYED_FRAGMENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render(renderFn(['one', 'two']), root)
|
||||||
|
expect(serializeInner(root)).toBe(
|
||||||
|
`<!--comment--><span></span><div>one</div><!--comment--><span></span><div>two</div>`
|
||||||
|
)
|
||||||
|
|
||||||
|
render(renderFn(['two', 'one']), root)
|
||||||
|
expect(serializeInner(root)).toBe(
|
||||||
|
`<!--comment--><span></span><div>two</div><!--comment--><span></span><div>one</div>`
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1153,8 +1153,10 @@ function baseCreateRenderer(
|
|||||||
parentSuspense,
|
parentSuspense,
|
||||||
isSVG
|
isSVG
|
||||||
)
|
)
|
||||||
if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
|
// #2080 if the stable fragment has a key, it's a <template v-for> that may
|
||||||
traverseStaticChildren(n1, n2)
|
// get moved around. Make sure all root level vnodes inherit el.
|
||||||
|
if (n2.key != null) {
|
||||||
|
traverseStaticChildren(n1, n2, true /* shallow */)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// keyed / unkeyed, or manual fragments.
|
// keyed / unkeyed, or manual fragments.
|
||||||
@ -2166,9 +2168,12 @@ function baseCreateRenderer(
|
|||||||
* inside a block also inherit the DOM element from the previous tree so that
|
* inside a block also inherit the DOM element from the previous tree so that
|
||||||
* HMR updates (which are full updates) can retrieve the element for patching.
|
* HMR updates (which are full updates) can retrieve the element for patching.
|
||||||
*
|
*
|
||||||
* Dev only.
|
* #2080
|
||||||
|
* Inside keyed `template` fragment static children, if a fragment is moved,
|
||||||
|
* the children will always moved so that need inherit el form previous nodes
|
||||||
|
* to ensure correct moved position.
|
||||||
*/
|
*/
|
||||||
const traverseStaticChildren = (n1: VNode, n2: VNode) => {
|
const traverseStaticChildren = (n1: VNode, n2: VNode, shallow = false) => {
|
||||||
const ch1 = n1.children
|
const ch1 = n1.children
|
||||||
const ch2 = n2.children
|
const ch2 = n2.children
|
||||||
if (isArray(ch1) && isArray(ch2)) {
|
if (isArray(ch1) && isArray(ch2)) {
|
||||||
@ -2181,7 +2186,10 @@ function baseCreateRenderer(
|
|||||||
if (c2.patchFlag <= 0 || c2.patchFlag === PatchFlags.HYDRATE_EVENTS) {
|
if (c2.patchFlag <= 0 || c2.patchFlag === PatchFlags.HYDRATE_EVENTS) {
|
||||||
c2.el = c1.el
|
c2.el = c1.el
|
||||||
}
|
}
|
||||||
traverseStaticChildren(c1, c2)
|
if (!shallow) traverseStaticChildren(c1, c2)
|
||||||
|
}
|
||||||
|
if (__DEV__ && c2.type === Comment) {
|
||||||
|
c2.el = c1.el
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user