Просмотр исходного кода

fix(runtime-core): mount children before setting element props

fix #1318, close #1320
Evan You 5 лет назад
Родитель
Сommit
8084156f4d

+ 17 - 14
packages/runtime-core/src/renderer.ts

@@ -672,6 +672,23 @@ function baseCreateRenderer(
         isSVG,
         props && props.is
       )
+
+      // mount children first, since some props may rely on child content
+      // being already rendered, e.g. `<select value>`
+      if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
+        hostSetElementText(el, vnode.children as string)
+      } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+        mountChildren(
+          vnode.children as VNodeArrayChildren,
+          el,
+          null,
+          parentComponent,
+          parentSuspense,
+          isSVG && type !== 'foreignObject',
+          optimized || !!vnode.dynamicChildren
+        )
+      }
+
       // props
       if (props) {
         for (const key in props) {
@@ -707,20 +724,6 @@ function baseCreateRenderer(
         hostSetScopeId(el, treeOwnerId + '-s')
       }
 
-      // children
-      if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
-        hostSetElementText(el, vnode.children as string)
-      } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
-        mountChildren(
-          vnode.children as VNodeArrayChildren,
-          el,
-          null,
-          parentComponent,
-          parentSuspense,
-          isSVG && type !== 'foreignObject',
-          optimized || !!vnode.dynamicChildren
-        )
-      }
       if (transition && !transition.persisted) {
         transition.beforeEnter(el)
       }

+ 6 - 6
packages/runtime-test/__tests__/testRuntime.spec.ts

@@ -77,6 +77,12 @@ describe('test renderer', () => {
     })
 
     expect(ops[1]).toEqual({
+      type: NodeOpTypes.SET_ELEMENT_TEXT,
+      text: 'hello',
+      targetNode: root.children[0]
+    })
+
+    expect(ops[2]).toEqual({
       type: NodeOpTypes.PATCH,
       targetNode: root.children[0],
       propKey: 'id',
@@ -84,12 +90,6 @@ describe('test renderer', () => {
       propNextValue: 'test'
     })
 
-    expect(ops[2]).toEqual({
-      type: NodeOpTypes.SET_ELEMENT_TEXT,
-      text: 'hello',
-      targetNode: root.children[0]
-    })
-
     expect(ops[3]).toEqual({
       type: NodeOpTypes.INSERT,
       targetNode: root.children[0],