fix(runtime-core): patchChildren first in patchElement (#4313)
This commit is contained in:
		
							parent
							
								
									cd2d98499e
								
							
						
					
					
						commit
						5b3f1e8424
					
				@ -840,6 +840,35 @@ function baseCreateRenderer(
 | 
				
			|||||||
      dynamicChildren = null
 | 
					      dynamicChildren = null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
 | 
				
			||||||
 | 
					    if (dynamicChildren) {
 | 
				
			||||||
 | 
					      patchBlockChildren(
 | 
				
			||||||
 | 
					        n1.dynamicChildren!,
 | 
				
			||||||
 | 
					        dynamicChildren,
 | 
				
			||||||
 | 
					        el,
 | 
				
			||||||
 | 
					        parentComponent,
 | 
				
			||||||
 | 
					        parentSuspense,
 | 
				
			||||||
 | 
					        areChildrenSVG,
 | 
				
			||||||
 | 
					        slotScopeIds
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
 | 
				
			||||||
 | 
					        traverseStaticChildren(n1, n2)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else if (!optimized) {
 | 
				
			||||||
 | 
					      // full diff
 | 
				
			||||||
 | 
					      patchChildren(
 | 
				
			||||||
 | 
					        n1,
 | 
				
			||||||
 | 
					        n2,
 | 
				
			||||||
 | 
					        el,
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        parentComponent,
 | 
				
			||||||
 | 
					        parentSuspense,
 | 
				
			||||||
 | 
					        areChildrenSVG,
 | 
				
			||||||
 | 
					        slotScopeIds,
 | 
				
			||||||
 | 
					        false
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (patchFlag > 0) {
 | 
					    if (patchFlag > 0) {
 | 
				
			||||||
      // the presence of a patchFlag means this element's render code was
 | 
					      // the presence of a patchFlag means this element's render code was
 | 
				
			||||||
      // generated by the compiler and can take the fast path.
 | 
					      // generated by the compiler and can take the fast path.
 | 
				
			||||||
@ -922,35 +951,6 @@ function baseCreateRenderer(
 | 
				
			|||||||
      )
 | 
					      )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
 | 
					 | 
				
			||||||
    if (dynamicChildren) {
 | 
					 | 
				
			||||||
      patchBlockChildren(
 | 
					 | 
				
			||||||
        n1.dynamicChildren!,
 | 
					 | 
				
			||||||
        dynamicChildren,
 | 
					 | 
				
			||||||
        el,
 | 
					 | 
				
			||||||
        parentComponent,
 | 
					 | 
				
			||||||
        parentSuspense,
 | 
					 | 
				
			||||||
        areChildrenSVG,
 | 
					 | 
				
			||||||
        slotScopeIds
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      if (__DEV__ && parentComponent && parentComponent.type.__hmrId) {
 | 
					 | 
				
			||||||
        traverseStaticChildren(n1, n2)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else if (!optimized) {
 | 
					 | 
				
			||||||
      // full diff
 | 
					 | 
				
			||||||
      patchChildren(
 | 
					 | 
				
			||||||
        n1,
 | 
					 | 
				
			||||||
        n2,
 | 
					 | 
				
			||||||
        el,
 | 
					 | 
				
			||||||
        null,
 | 
					 | 
				
			||||||
        parentComponent,
 | 
					 | 
				
			||||||
        parentSuspense,
 | 
					 | 
				
			||||||
        areChildrenSVG,
 | 
					 | 
				
			||||||
        slotScopeIds,
 | 
					 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
 | 
					    if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
 | 
				
			||||||
      queuePostRenderEffect(() => {
 | 
					      queuePostRenderEffect(() => {
 | 
				
			||||||
        vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1)
 | 
					        vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1)
 | 
				
			||||||
 | 
				
			|||||||
@ -192,4 +192,26 @@ describe('runtime-dom: props patching', () => {
 | 
				
			|||||||
    patchProp(el, 'size', 100, null)
 | 
					    patchProp(el, 'size', 100, null)
 | 
				
			||||||
    expect(el.getAttribute('size')).toBe(null)
 | 
					    expect(el.getAttribute('size')).toBe(null)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('patch value for select', () => {
 | 
				
			||||||
 | 
					    const root = document.createElement('div')
 | 
				
			||||||
 | 
					    render(
 | 
				
			||||||
 | 
					      h('select', { value: 'foo' }, [
 | 
				
			||||||
 | 
					        h('option', { value: 'foo' }, 'foo'),
 | 
				
			||||||
 | 
					        h('option', { value: 'bar' }, 'bar')
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      root
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    const el = root.children[0] as HTMLSelectElement
 | 
				
			||||||
 | 
					    expect(el.value).toBe('foo')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render(
 | 
				
			||||||
 | 
					      h('select', { value: 'baz' }, [
 | 
				
			||||||
 | 
					        h('option', { value: 'foo' }, 'foo'),
 | 
				
			||||||
 | 
					        h('option', { value: 'baz' }, 'baz')
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      root
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    expect(el.value).toBe('baz')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
				
			|||||||
@ -103,18 +103,18 @@ describe('test renderer', () => {
 | 
				
			|||||||
    expect(updateOps.length).toBe(2)
 | 
					    expect(updateOps.length).toBe(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(updateOps[0]).toEqual({
 | 
					    expect(updateOps[0]).toEqual({
 | 
				
			||||||
 | 
					      type: NodeOpTypes.SET_ELEMENT_TEXT,
 | 
				
			||||||
 | 
					      targetNode: root.children[0],
 | 
				
			||||||
 | 
					      text: 'bar'
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(updateOps[1]).toEqual({
 | 
				
			||||||
      type: NodeOpTypes.PATCH,
 | 
					      type: NodeOpTypes.PATCH,
 | 
				
			||||||
      targetNode: root.children[0],
 | 
					      targetNode: root.children[0],
 | 
				
			||||||
      propKey: 'id',
 | 
					      propKey: 'id',
 | 
				
			||||||
      propPrevValue: 'test',
 | 
					      propPrevValue: 'test',
 | 
				
			||||||
      propNextValue: 'foo'
 | 
					      propNextValue: 'foo'
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					 | 
				
			||||||
    expect(updateOps[1]).toEqual({
 | 
					 | 
				
			||||||
      type: NodeOpTypes.SET_ELEMENT_TEXT,
 | 
					 | 
				
			||||||
      targetNode: root.children[0],
 | 
					 | 
				
			||||||
      text: 'bar'
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should be able to serialize nodes', () => {
 | 
					  it('should be able to serialize nodes', () => {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user