|
1 | 1 | import * as CompilerDOM from '@vue/compiler-dom'; |
2 | 2 | import type { Code } from '../../types'; |
| 3 | +import { hyphenateTag } from '../../utils/shared'; |
3 | 4 | import { endOfLine, newLine } from '../utils'; |
4 | 5 | import type { TemplateCodegenContext } from './context'; |
5 | 6 | import { generateComponent, generateElement } from './element'; |
@@ -66,18 +67,16 @@ export function* generateTemplateChild( |
66 | 67 | } |
67 | 68 | } |
68 | 69 |
|
69 | | - const shouldInheritRootNodeAttrs = options.inheritAttrs; |
70 | | - |
71 | 70 | const cur = node as CompilerDOM.ElementNode | CompilerDOM.IfNode | CompilerDOM.ForNode; |
72 | 71 | if (cur.codegenNode?.type === CompilerDOM.NodeTypes.JS_CACHE_EXPRESSION) { |
73 | 72 | cur.codegenNode = cur.codegenNode.value as any; |
74 | 73 | } |
75 | 74 |
|
76 | 75 | if (node.type === CompilerDOM.NodeTypes.ROOT) { |
77 | | - let prev: CompilerDOM.TemplateChildNode | undefined; |
78 | | - if (shouldInheritRootNodeAttrs && node.children.length === 1 && node.children[0].type === CompilerDOM.NodeTypes.ELEMENT) { |
79 | | - ctx.singleRootNode = node.children[0]; |
| 76 | + for (const item of collectSingleRootNodes(options, node.children)) { |
| 77 | + ctx.singleRootNodes.add(item); |
80 | 78 | } |
| 79 | + let prev: CompilerDOM.TemplateChildNode | undefined; |
81 | 80 | for (const childNode of node.children) { |
82 | 81 | yield* generateTemplateChild(options, ctx, childNode, prev); |
83 | 82 | prev = childNode; |
@@ -159,6 +158,36 @@ export function* generateTemplateChild( |
159 | 158 | } |
160 | 159 | } |
161 | 160 |
|
| 161 | +function* collectSingleRootNodes( |
| 162 | + options: TemplateCodegenOptions, |
| 163 | + children: CompilerDOM.TemplateChildNode[] |
| 164 | +): Generator<CompilerDOM.ElementNode | null> { |
| 165 | + if (children.length !== 1) { |
| 166 | + // "null" is used to determine whether the component is not always has a single root |
| 167 | + if (children.length > 1) { |
| 168 | + yield null; |
| 169 | + } |
| 170 | + return; |
| 171 | + } |
| 172 | + |
| 173 | + const child = children[0]; |
| 174 | + if (child.type === CompilerDOM.NodeTypes.IF) { |
| 175 | + for (const branch of child.branches) { |
| 176 | + yield* collectSingleRootNodes(options, branch.children); |
| 177 | + } |
| 178 | + return; |
| 179 | + } |
| 180 | + else if (child.type !== CompilerDOM.NodeTypes.ELEMENT) { |
| 181 | + return; |
| 182 | + } |
| 183 | + yield child; |
| 184 | + |
| 185 | + const tag = hyphenateTag(child.tag); |
| 186 | + if (options.vueCompilerOptions.fallthroughComponentNames.includes(tag)) { |
| 187 | + yield* collectSingleRootNodes(options, child.children); |
| 188 | + } |
| 189 | +} |
| 190 | + |
162 | 191 | // TODO: track https://github.com/vuejs/vue-next/issues/3498 |
163 | 192 | export function getVForNode(node: CompilerDOM.ElementNode) { |
164 | 193 | const forDirective = node.props.find( |
|
0 commit comments