refactor(compiler-core): emit error on v-if key usage
This commit is contained in:
parent
355c052622
commit
58b4a382f9
@ -145,17 +145,3 @@ return function render(_ctx, _cache) {
|
|||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`compiler: v-if codegen v-if with key 1`] = `
|
|
||||||
"const _Vue = Vue
|
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
|
||||||
with (_ctx) {
|
|
||||||
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
|
|
||||||
|
|
||||||
return ok
|
|
||||||
? (_openBlock(), _createBlock(\\"div\\", { key: \\"some-key\\" }))
|
|
||||||
: _createCommentVNode(\\"v-if\\", true)
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
@ -282,6 +282,16 @@ describe('compiler: v-if', () => {
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('error on user key', () => {
|
||||||
|
const onError = jest.fn()
|
||||||
|
parseWithIfTransform(`<div v-if="ok" :key="1" />`, { onError })
|
||||||
|
expect(onError.mock.calls[0]).toMatchObject([
|
||||||
|
{
|
||||||
|
code: ErrorCodes.X_V_IF_KEY
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('codegen', () => {
|
describe('codegen', () => {
|
||||||
@ -581,18 +591,6 @@ describe('compiler: v-if', () => {
|
|||||||
expect(branch1.props).toMatchObject(createObjectMatcher({ key: `[0]` }))
|
expect(branch1.props).toMatchObject(createObjectMatcher({ key: `[0]` }))
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-if with key', () => {
|
|
||||||
const {
|
|
||||||
root,
|
|
||||||
node: { codegenNode }
|
|
||||||
} = parseWithIfTransform(`<div v-if="ok" key="some-key"/>`)
|
|
||||||
expect(codegenNode.consequent).toMatchObject({
|
|
||||||
tag: `"div"`,
|
|
||||||
props: createObjectMatcher({ key: 'some-key' })
|
|
||||||
})
|
|
||||||
expect(generate(root).code).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('with comments', () => {
|
test('with comments', () => {
|
||||||
const { node } = parseWithIfTransform(`
|
const { node } = parseWithIfTransform(`
|
||||||
<template v-if="ok">
|
<template v-if="ok">
|
||||||
|
@ -63,6 +63,7 @@ export const enum ErrorCodes {
|
|||||||
|
|
||||||
// transform errors
|
// transform errors
|
||||||
X_V_IF_NO_EXPRESSION,
|
X_V_IF_NO_EXPRESSION,
|
||||||
|
X_V_IF_KEY,
|
||||||
X_V_ELSE_NO_ADJACENT_IF,
|
X_V_ELSE_NO_ADJACENT_IF,
|
||||||
X_V_FOR_NO_EXPRESSION,
|
X_V_FOR_NO_EXPRESSION,
|
||||||
X_V_FOR_MALFORMED_EXPRESSION,
|
X_V_FOR_MALFORMED_EXPRESSION,
|
||||||
@ -135,6 +136,7 @@ export const errorMessages: { [code: number]: string } = {
|
|||||||
|
|
||||||
// transform errors
|
// transform errors
|
||||||
[ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
|
[ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
|
||||||
|
[ErrorCodes.X_V_IF_KEY]: `v-if branches must use compiler generated keys.`,
|
||||||
[ErrorCodes.X_V_ELSE_NO_ADJACENT_IF]: `v-else/v-else-if has no adjacent v-if.`,
|
[ErrorCodes.X_V_ELSE_NO_ADJACENT_IF]: `v-else/v-else-if has no adjacent v-if.`,
|
||||||
[ErrorCodes.X_V_FOR_NO_EXPRESSION]: `v-for is missing expression.`,
|
[ErrorCodes.X_V_FOR_NO_EXPRESSION]: `v-for is missing expression.`,
|
||||||
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
|
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
|
||||||
|
@ -30,7 +30,7 @@ import {
|
|||||||
OPEN_BLOCK,
|
OPEN_BLOCK,
|
||||||
TELEPORT
|
TELEPORT
|
||||||
} from '../runtimeHelpers'
|
} from '../runtimeHelpers'
|
||||||
import { injectProp, findDir } from '../utils'
|
import { injectProp, findDir, findProp } from '../utils'
|
||||||
import { PatchFlags, PatchFlagNames } from '@vue/shared'
|
import { PatchFlags, PatchFlagNames } from '@vue/shared'
|
||||||
|
|
||||||
export const transformIf = createStructuralDirectiveTransform(
|
export const transformIf = createStructuralDirectiveTransform(
|
||||||
@ -111,6 +111,11 @@ export function processIf(
|
|||||||
validateBrowserExpression(dir.exp as SimpleExpressionNode, context)
|
validateBrowserExpression(dir.exp as SimpleExpressionNode, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userKey = /*#__PURE__*/ findProp(node, 'key')
|
||||||
|
if (userKey) {
|
||||||
|
context.onError(createCompilerError(ErrorCodes.X_V_IF_KEY, userKey.loc))
|
||||||
|
}
|
||||||
|
|
||||||
if (dir.name === 'if') {
|
if (dir.name === 'if') {
|
||||||
const branch = createIfBranch(node, dir)
|
const branch = createIfBranch(node, dir)
|
||||||
const ifNode: IfNode = {
|
const ifNode: IfNode = {
|
||||||
@ -175,13 +180,13 @@ function createIfBranch(node: ElementNode, dir: DirectiveNode): IfBranchNode {
|
|||||||
|
|
||||||
function createCodegenNodeForBranch(
|
function createCodegenNodeForBranch(
|
||||||
branch: IfBranchNode,
|
branch: IfBranchNode,
|
||||||
index: number,
|
keyIndex: number,
|
||||||
context: TransformContext
|
context: TransformContext
|
||||||
): IfConditionalExpression | BlockCodegenNode {
|
): IfConditionalExpression | BlockCodegenNode {
|
||||||
if (branch.condition) {
|
if (branch.condition) {
|
||||||
return createConditionalExpression(
|
return createConditionalExpression(
|
||||||
branch.condition,
|
branch.condition,
|
||||||
createChildrenCodegenNode(branch, index, context),
|
createChildrenCodegenNode(branch, keyIndex, context),
|
||||||
// make sure to pass in asBlock: true so that the comment node call
|
// make sure to pass in asBlock: true so that the comment node call
|
||||||
// closes the current block.
|
// closes the current block.
|
||||||
createCallExpression(context.helper(CREATE_COMMENT), [
|
createCallExpression(context.helper(CREATE_COMMENT), [
|
||||||
@ -190,19 +195,19 @@ function createCodegenNodeForBranch(
|
|||||||
])
|
])
|
||||||
) as IfConditionalExpression
|
) as IfConditionalExpression
|
||||||
} else {
|
} else {
|
||||||
return createChildrenCodegenNode(branch, index, context)
|
return createChildrenCodegenNode(branch, keyIndex, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChildrenCodegenNode(
|
function createChildrenCodegenNode(
|
||||||
branch: IfBranchNode,
|
branch: IfBranchNode,
|
||||||
index: number,
|
keyIndex: number,
|
||||||
context: TransformContext
|
context: TransformContext
|
||||||
): BlockCodegenNode {
|
): BlockCodegenNode {
|
||||||
const { helper } = context
|
const { helper } = context
|
||||||
const keyProperty = createObjectProperty(
|
const keyProperty = createObjectProperty(
|
||||||
`key`,
|
`key`,
|
||||||
createSimpleExpression(index + '', false)
|
createSimpleExpression(`${keyIndex}`, false)
|
||||||
)
|
)
|
||||||
const { children } = branch
|
const { children } = branch
|
||||||
const firstChild = children[0]
|
const firstChild = children[0]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user