}"
`;
+exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
+
+ return (_openBlock(), _createBlock(_Fragment, null, [
+ ok
+ ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
+ : (_openBlock(), _createBlock(\\"p\\", { key: 1 })),
+ another
+ ? (_openBlock(), _createBlock(\\"div\\", { key: 2 }))
+ : orNot
+ ? (_openBlock(), _createBlock(\\"p\\", { key: 3 }))
+ : (_openBlock(), _createBlock(\\"p\\", { key: 4 }))
+ ], 64 /* STABLE_FRAGMENT */))
+ }
+}"
+`;
+
+exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have different keys 1`] = `
+"const _Vue = Vue
+
+return function render(_ctx, _cache) {
+ with (_ctx) {
+ const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
+
+ return (_openBlock(), _createBlock(_Fragment, null, [
+ ok
+ ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
+ : _createCommentVNode(\\"v-if\\", true),
+ orNot
+ ? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
+ : _createCommentVNode(\\"v-if\\", true)
+ ], 64 /* STABLE_FRAGMENT */))
+ }
+}"
+`;
+
exports[`compiler: v-if codegen template v-if 1`] = `
"const _Vue = Vue
function parseWithIfTransform(
template: string,
options: CompilerOptions = {},
- returnIndex: number = 0
+ returnIndex: number = 0,
+ childrenLen: number = 1
) {
const ast = parse(template, options)
transform(ast, {
...options
})
if (!options.onError) {
- expect(ast.children.length).toBe(1)
- expect(ast.children[0].type).toBe(NodeTypes.IF)
+ expect(ast.children.length).toBe(childrenLen)
+ for (let i = 0; i < childrenLen; i++) {
+ expect(ast.children[i].type).toBe(NodeTypes.IF)
+ }
}
return {
root: ast,
expect(generate(root).code).toMatchSnapshot()
})
+ test('multiple v-if that are sibling nodes should have different keys', () => {
+ const { root } = parseWithIfTransform(
+ `<div v-if="ok"/><p v-if="orNot"/>`,
+ {},
+ 0 /* returnIndex, just give the default value */,
+ 2 /* childrenLen */
+ )
+
+ const ifNode = root.children[0] as IfNode & {
+ codegenNode: IfConditionalExpression
+ }
+ expect(ifNode.codegenNode.consequent).toMatchObject({
+ tag: `"div"`,
+ props: createObjectMatcher({ key: `[0]` })
+ })
+ const ifNode2 = root.children[1] as IfNode & {
+ codegenNode: IfConditionalExpression
+ }
+ expect(ifNode2.codegenNode.consequent).toMatchObject({
+ tag: `"p"`,
+ props: createObjectMatcher({ key: `[1]` })
+ })
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
+ test('increasing key: v-if + v-else-if + v-else', () => {
+ const { root } = parseWithIfTransform(
+ `<div v-if="ok"/><p v-else/><div v-if="another"/><p v-else-if="orNot"/><p v-else/>`,
+ {},
+ 0 /* returnIndex, just give the default value */,
+ 2 /* childrenLen */
+ )
+ const ifNode = root.children[0] as IfNode & {
+ codegenNode: IfConditionalExpression
+ }
+ expect(ifNode.codegenNode.consequent).toMatchObject({
+ tag: `"div"`,
+ props: createObjectMatcher({ key: `[0]` })
+ })
+ expect(ifNode.codegenNode.alternate).toMatchObject({
+ tag: `"p"`,
+ props: createObjectMatcher({ key: `[1]` })
+ })
+ const ifNode2 = root.children[1] as IfNode & {
+ codegenNode: IfConditionalExpression
+ }
+ expect(ifNode2.codegenNode.consequent).toMatchObject({
+ tag: `"div"`,
+ props: createObjectMatcher({ key: `[2]` })
+ })
+ const branch = ifNode2.codegenNode.alternate as IfConditionalExpression
+ expect(branch.consequent).toMatchObject({
+ tag: `"p"`,
+ props: createObjectMatcher({ key: `[3]` })
+ })
+ expect(branch.alternate).toMatchObject({
+ tag: `"p"`,
+ props: createObjectMatcher({ key: `[4]` })
+ })
+ expect(generate(root).code).toMatchSnapshot()
+ })
+
test('key injection (only v-bind)', () => {
const {
node: { codegenNode }
/^(if|else|else-if)$/,
(node, dir, context) => {
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
+ // #1587: We need to dynamically increment the key based on the current
+ // node's sibling nodes, since chained v-if/else branches are
+ // rendered at the same depth
+ const siblings = context.parent!.children
+ let i = siblings.indexOf(ifNode)
+ let key = 0
+ while (i-- >= 0) {
+ const sibling = siblings[i]
+ if (sibling && sibling.type === NodeTypes.IF) {
+ key += sibling.branches.length
+ }
+ }
+
// Exit callback. Complete the codegenNode when all children have been
// transformed.
return () => {
if (isRoot) {
ifNode.codegenNode = createCodegenNodeForBranch(
branch,
- 0,
+ key,
context
) as IfConditionalExpression
} else {
}
parentCondition.alternate = createCodegenNodeForBranch(
branch,
- ifNode.branches.length - 1,
+ key + ifNode.branches.length - 1,
context
)
}