diff --git a/packages/taro-transformer-wx/src/render.ts b/packages/taro-transformer-wx/src/render.ts index c2377ae83cd5..fddc9491f9dc 100644 --- a/packages/taro-transformer-wx/src/render.ts +++ b/packages/taro-transformer-wx/src/render.ts @@ -556,11 +556,10 @@ export class RenderParser { blockStatement.traverse(this.renameIfScopeVaribale(blockStatement)) } if (t.isIdentifier(parentNode.left)) { - const name = parentNode.left.name - const bindingNode = this.renderScope.getOwnBinding(name)!.path.node - const block = this.templates.get(name) || buildBlockElement() + const assignmentName = parentNode.left.name + const bindingNode = this.renderScope.getOwnBinding(assignmentName)!.path.node + const block = this.templates.get(assignmentName) || buildBlockElement() if (isEmptyDeclarator(bindingNode)) { - const ifStatement = parentPath.findParent(p => p.isIfStatement()) const blockStatement = parentPath.findParent(p => p.isBlockStatement() ) @@ -572,7 +571,52 @@ export class RenderParser { const parentIfStatement = ifStatement.findParent(p => p.isIfStatement() ) as NodePath - if (parentIfStatement && parentIfStatement.get('alternate') === ifStatement) { + const assignments: t.AssignmentExpression[] = [] + let isAssignedBefore = false + // @TODO: 重构这两种循环为通用模块 + + // 如果这个 JSX assigmnent 的作用域中有其他的 if block 曾经赋值过,它应该是 else-if + if (blockStatement && blockStatement.isBlockStatement()) { + for (const parentStatement of blockStatement.node.body) { + if (t.isIfStatement(parentStatement) && t.isBlockStatement(parentStatement.consequent)) { + const statements = parentStatement.consequent.body + for (const statement of statements) { + if (t.isExpressionStatement(statement) && t.isAssignmentExpression(statement.expression) && t.isIdentifier(statement.expression.left, { name: assignmentName })) { + isAssignedBefore = true + } + } + } + } + } + + // 如果这个 JSX assigmnent 的的父级作用域中的 prev sibling 有相同的赋值,它应该是 else-if + if (parentIfStatement) { + const { consequent } = parentIfStatement.node + if (t.isBlockStatement(consequent)) { + const body = consequent.body + for (const parentStatement of body) { + if (t.isIfStatement(parentStatement) && t.isBlockStatement(parentStatement.consequent)) { + const statements = parentStatement.consequent.body + for (const statement of statements) { + if (t.isExpressionStatement(statement) && t.isAssignmentExpression(statement.expression) && t.isIdentifier(statement.expression.left, { name: assignmentName })) { + assignments.push(statement.expression) + } + } + } + } + } + } + if ( + ( + parentIfStatement && + ( + parentIfStatement.get('alternate') === ifStatement || + assignments.findIndex(a => a === parentNode) > 0 + ) + ) + || + isAssignedBefore + ) { setJSXAttr( jsxElementPath.node, Adapter.elseif, @@ -588,7 +632,7 @@ export class RenderParser { } block.children.push(jsxElementPath.node) // setTemplate(name, path, templates) - name && this.templates.set(name, block) + assignmentName && this.templates.set(assignmentName, block) } } else { throw codeFrameError(