]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(sfc): fix scoped style regression for child component with single root + comment
authorEvan You <yyx990803@gmail.com>
Fri, 4 Sep 2020 15:36:55 +0000 (11:36 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 4 Sep 2020 15:36:55 +0000 (11:36 -0400)
fix #2046

packages/runtime-core/src/componentRenderUtils.ts
packages/runtime-core/src/renderer.ts

index 9fa72c9dd511304e8ef93cddbb37facbb4661759..fe1a73fb21e6ced9f4257904823da96994f249c9 100644 (file)
@@ -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) {
index ee020298423855209ba82b0b84ad81d5008e5c5a..a4cf97dc8077feef5ddb00d943805aa84cdacdaf 100644 (file)
@@ -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,