}
}"
`;
-
-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)
- }
-}"
-`;
}
])
})
+
+ 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', () => {
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', () => {
const { node } = parseWithIfTransform(`
<template v-if="ok">
// transform errors
X_V_IF_NO_EXPRESSION,
+ X_V_IF_KEY,
X_V_ELSE_NO_ADJACENT_IF,
X_V_FOR_NO_EXPRESSION,
X_V_FOR_MALFORMED_EXPRESSION,
// transform errors
[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_FOR_NO_EXPRESSION]: `v-for is missing expression.`,
[ErrorCodes.X_V_FOR_MALFORMED_EXPRESSION]: `v-for has invalid expression.`,
OPEN_BLOCK,
TELEPORT
} from '../runtimeHelpers'
-import { injectProp, findDir } from '../utils'
+import { injectProp, findDir, findProp } from '../utils'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
export const transformIf = createStructuralDirectiveTransform(
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') {
const branch = createIfBranch(node, dir)
const ifNode: IfNode = {
function createCodegenNodeForBranch(
branch: IfBranchNode,
- index: number,
+ keyIndex: number,
context: TransformContext
): IfConditionalExpression | BlockCodegenNode {
if (branch.condition) {
return createConditionalExpression(
branch.condition,
- createChildrenCodegenNode(branch, index, context),
+ createChildrenCodegenNode(branch, keyIndex, context),
// make sure to pass in asBlock: true so that the comment node call
// closes the current block.
createCallExpression(context.helper(CREATE_COMMENT), [
])
) as IfConditionalExpression
} else {
- return createChildrenCodegenNode(branch, index, context)
+ return createChildrenCodegenNode(branch, keyIndex, context)
}
}
function createChildrenCodegenNode(
branch: IfBranchNode,
- index: number,
+ keyIndex: number,
context: TransformContext
): BlockCodegenNode {
const { helper } = context
const keyProperty = createObjectProperty(
`key`,
- createSimpleExpression(index + '', false)
+ createSimpleExpression(`${keyIndex}`, false)
)
const { children } = branch
const firstChild = children[0]