fix(compiler-core): fix v-if + v-for on <template>

fix #1637
This commit is contained in:
Evan You 2020-07-19 14:36:01 -04:00
parent 0526e5d7fa
commit af7e100ef2
4 changed files with 60 additions and 3 deletions

View File

@ -180,6 +180,22 @@ return function render(_ctx, _cache) {
}"
`;
exports[`compiler: v-for codegen v-if + v-for on <template> 1`] = `
"const _Vue = Vue
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createBlock(_Fragment, null, [], 64 /* STABLE_FRAGMENT */))
}), 256 /* UNKEYED_FRAGMENT */))
: _createCommentVNode(\\"v-if\\", true)
}
}"
`;
exports[`compiler: v-for codegen value + key + index 1`] = `
"const _Vue = Vue

View File

@ -840,6 +840,44 @@ describe('compiler: v-for', () => {
expect(generate(root).code).toMatchSnapshot()
})
// 1637
test('v-if + v-for on <template>', () => {
const {
root,
node: { codegenNode }
} = parseWithForTransform(`<template v-if="ok" v-for="i in list"/>`)
expect(codegenNode).toMatchObject({
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
test: { content: `ok` },
consequent: {
type: NodeTypes.VNODE_CALL,
props: createObjectMatcher({
key: `[0]`
}),
isBlock: true,
disableTracking: true,
patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
arguments: [
{ content: `list` },
{
type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: [{ content: `i` }],
returns: {
type: NodeTypes.VNODE_CALL,
tag: FRAGMENT,
isBlock: true
}
}
]
}
}
})
expect(generate(root).code).toMatchSnapshot()
})
test('v-for on element with custom directive', () => {
const {
root,

View File

@ -82,7 +82,7 @@ export const transformFor = createStructuralDirectiveTransform(
const isTemplate = isTemplateNode(node)
const { children } = forNode
const needFragmentWrapper =
children.length > 1 || children[0].type !== NodeTypes.ELEMENT
children.length !== 1 || children[0].type !== NodeTypes.ELEMENT
const slotOutlet = isSlotOutlet(node)
? node
: isTemplate &&

View File

@ -30,7 +30,7 @@ import {
OPEN_BLOCK,
TELEPORT
} from '../runtimeHelpers'
import { injectProp } from '../utils'
import { injectProp, findDir } from '../utils'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
export const transformIf = createStructuralDirectiveTransform(
@ -166,7 +166,10 @@ function createIfBranch(node: ElementNode, dir: DirectiveNode): IfBranchNode {
type: NodeTypes.IF_BRANCH,
loc: node.loc,
condition: dir.name === 'else' ? undefined : dir.exp,
children: node.tagType === ElementTypes.TEMPLATE ? node.children : [node]
children:
node.tagType === ElementTypes.TEMPLATE && !findDir(node, 'for')
? node.children
: [node]
}
}