dx(compiler-core): warn on <template v-for> key misplacement

Note: the behavior is different from Vue 2. `<template v-for>` are compiled
into an array of Fragment vnodes so the key should be placed the `<template>`
for v-for to use it for diffing.
This commit is contained in:
Evan You
2020-08-04 12:20:32 -04:00
parent de0c8a7e3e
commit b0d01e9db9
3 changed files with 50 additions and 2 deletions

View File

@@ -10,7 +10,6 @@ import {
SimpleExpressionNode,
createCallExpression,
createFunctionExpression,
ElementTypes,
createObjectExpression,
createObjectProperty,
ForCodegenNode,
@@ -81,6 +80,25 @@ export const transformFor = createStructuralDirectiveTransform(
let childBlock: BlockCodegenNode
const isTemplate = isTemplateNode(node)
const { children } = forNode
// check <template v-for> key placement
if ((__DEV__ || !__BROWSER__) && isTemplate) {
node.children.some(c => {
if (c.type === NodeTypes.ELEMENT) {
const key = findProp(c, 'key')
if (key) {
context.onError(
createCompilerError(
ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT,
key.loc
)
)
return true
}
}
})
}
const needFragmentWrapper =
children.length !== 1 || children[0].type !== NodeTypes.ELEMENT
const slotOutlet = isSlotOutlet(node)
@@ -183,7 +201,7 @@ export function processFor(
keyAlias: key,
objectIndexAlias: index,
parseResult,
children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node]
children: isTemplateNode(node) ? node.children : [node]
}
context.replaceNode(forNode)