|
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