From: Evan You Date: Fri, 4 Sep 2020 15:36:55 +0000 (-0400) Subject: fix(sfc): fix scoped style regression for child component with single root + comment X-Git-Tag: v3.0.0-rc.11~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dbc6c4cd0d298d3c6faa6d6aeb318be7a963700;p=thirdparty%2Fvuejs%2Fcore.git fix(sfc): fix scoped style regression for child component with single root + comment fix #2046 --- diff --git a/packages/runtime-core/src/componentRenderUtils.ts b/packages/runtime-core/src/componentRenderUtils.ts index 9fa72c9dd5..fe1a73fb21 100644 --- a/packages/runtime-core/src/componentRenderUtils.ts +++ b/packages/runtime-core/src/componentRenderUtils.ts @@ -214,6 +214,9 @@ export function renderComponentRoot( /** * dev only + * In dev mode, template root level comments are rendered, which turns the + * template into a fragment root, but we need to locate the single element + * root for attrs and scope id processing. */ const getChildRoot = ( vnode: VNode @@ -223,17 +226,10 @@ const getChildRoot = ( } const rawChildren = vnode.children as VNodeArrayChildren const dynamicChildren = vnode.dynamicChildren as VNodeArrayChildren - const children = rawChildren.filter(child => { - return !( - isVNode(child) && - child.type === Comment && - child.children !== 'v-if' - ) - }) - if (children.length !== 1) { + const childRoot = filterSingleRoot(rawChildren) + if (!childRoot) { return [vnode, undefined] } - const childRoot = children[0] const index = rawChildren.indexOf(childRoot) const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1 const setRoot = (updatedRoot: VNode) => { @@ -247,6 +243,20 @@ const getChildRoot = ( return [normalizeVNode(childRoot), setRoot] } +/** + * dev only + */ +export function filterSingleRoot(children: VNodeArrayChildren): VNode | null { + const filtered = children.filter(child => { + return !( + isVNode(child) && + child.type === Comment && + child.children !== 'v-if' + ) + }) + return filtered.length === 1 && isVNode(filtered[0]) ? filtered[0] : null +} + const getFunctionalFallthrough = (attrs: Data): Data | undefined => { let res: Data | undefined for (const key in attrs) { diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index ee02029842..a4cf97dc80 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -19,6 +19,7 @@ import { setupComponent } from './component' import { + filterSingleRoot, renderComponentRoot, shouldUpdateComponent, updateHOCHostEl @@ -746,30 +747,6 @@ function baseCreateRenderer( } // scopeId setScopeId(el, scopeId, vnode, parentComponent) - // if (scopeId) { - // hostSetScopeId(el, scopeId) - // } - // if (parentComponent) { - // const treeOwnerId = parentComponent.type.__scopeId - // // vnode's own scopeId and the current patched component's scopeId is - // // different - this is a slot content node. - // if (treeOwnerId && treeOwnerId !== scopeId) { - // hostSetScopeId(el, treeOwnerId + '-s') - // } - // const parentScopeId = - // vnode === parentComponent.subTree && parentComponent.vnode.scopeId - // if (parentScopeId) { - // hostSetScopeId(el, parentScopeId) - // if (parentComponent.parent) { - // const treeOwnerId = parentComponent.parent.type.__scopeId - // // vnode's own scopeId and the current patched component's scopeId is - // // different - this is a slot content node. - // if (treeOwnerId && treeOwnerId !== parentScopeId) { - // hostSetScopeId(el, treeOwnerId + '-s') - // } - // } - // } - // } } if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) { Object.defineProperty(el, '__vnode', { @@ -823,7 +800,12 @@ function baseCreateRenderer( if (treeOwnerId && treeOwnerId !== scopeId) { hostSetScopeId(el, treeOwnerId + '-s') } - if (vnode === parentComponent.subTree) { + let subTree = parentComponent.subTree + if (__DEV__ && subTree.type === Fragment) { + subTree = + filterSingleRoot(subTree.children as VNodeArrayChildren) || subTree + } + if (vnode === subTree) { setScopeId( el, parentComponent.vnode.scopeId,