fix(compiler-core): elements with dynamic keys should be forced into blocks
fix #916
This commit is contained in:
parent
2c9374dd91
commit
d531686f91
@ -292,10 +292,10 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic k
|
|||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
|
const { openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
return (_openBlock(), _createBlock(\\"div\\", null, [
|
return (_openBlock(), _createBlock(\\"div\\", null, [
|
||||||
_createVNode(\\"div\\", { key: foo })
|
(_openBlock(), _createBlock(\\"div\\", { key: foo }))
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
|
@ -36,7 +36,7 @@ exports[`compiler: v-for codegen keyed v-for 1`] = `
|
|||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
|
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
|
||||||
|
|
||||||
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
|
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
|
||||||
return (_openBlock(), _createBlock(\\"span\\", { key: item }))
|
return (_openBlock(), _createBlock(\\"span\\", { key: item }))
|
||||||
|
@ -861,4 +861,17 @@ describe('compiler: element transform', () => {
|
|||||||
isBlock: true
|
isBlock: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #938
|
||||||
|
test('element with dynamic keys should be forced into blocks', () => {
|
||||||
|
const ast = parse(`<div><div :key="foo" /></div>`)
|
||||||
|
transform(ast, {
|
||||||
|
nodeTransforms: [transformElement]
|
||||||
|
})
|
||||||
|
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
|
||||||
|
type: NodeTypes.VNODE_CALL,
|
||||||
|
tag: `"div"`,
|
||||||
|
isBlock: true
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -77,12 +77,16 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
let dynamicPropNames: string[] | undefined
|
let dynamicPropNames: string[] | undefined
|
||||||
let vnodeDirectives: VNodeCall['directives']
|
let vnodeDirectives: VNodeCall['directives']
|
||||||
|
|
||||||
|
let shouldUseBlock =
|
||||||
|
!isComponent &&
|
||||||
// <svg> and <foreignObject> must be forced into blocks so that block
|
// <svg> and <foreignObject> must be forced into blocks so that block
|
||||||
// updates inside get proper isSVG flag at runtime. (#639, #643)
|
// updates inside get proper isSVG flag at runtime. (#639, #643)
|
||||||
// This is technically web-specific, but splitting the logic out of core
|
// This is technically web-specific, but splitting the logic out of core
|
||||||
// leads to too much unnecessary complexity.
|
// leads to too much unnecessary complexity.
|
||||||
let shouldUseBlock =
|
(tag === 'svg' ||
|
||||||
!isComponent && (tag === 'svg' || tag === 'foreignObject')
|
tag === 'foreignObject' ||
|
||||||
|
// #938: elements with dynamic keys should be forced into blocks
|
||||||
|
findProp(node, 'key', true))
|
||||||
|
|
||||||
// props
|
// props
|
||||||
if (props.length > 0) {
|
if (props.length > 0) {
|
||||||
@ -188,7 +192,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
vnodePatchFlag,
|
vnodePatchFlag,
|
||||||
vnodeDynamicProps,
|
vnodeDynamicProps,
|
||||||
vnodeDirectives,
|
vnodeDirectives,
|
||||||
shouldUseBlock,
|
!!shouldUseBlock,
|
||||||
false /* isForBlock */,
|
false /* isForBlock */,
|
||||||
node.loc
|
node.loc
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user