diff --git a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts index 136a0125610..6ee03207477 100644 --- a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts +++ b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts @@ -6,7 +6,9 @@ import { mergeProps, ref, onUpdated, - defineComponent + defineComponent, + openBlock, + createBlock } from '@vue/runtime-dom' import { mockWarn } from '@vue/shared' @@ -346,4 +348,36 @@ describe('attribute fallthrough', () => { expect(`Extraneous non-props attributes`).not.toHaveBeenWarned() expect(root.innerHTML).toBe(`
`) }) + + // #677 + it('should update merged dynamic attrs on optimized child root', async () => { + const id = ref('foo') + const cls = ref('bar') + const Parent = { + render() { + return h(Child, { id: id.value, class: cls.value }) + } + } + + const Child = { + props: [], + render() { + return openBlock(), createBlock('div') + } + } + + const root = document.createElement('div') + document.body.appendChild(root) + render(h(Parent), root) + + expect(root.innerHTML).toBe(`
`) + + id.value = 'fooo' + await nextTick() + expect(root.innerHTML).toBe(`
`) + + cls.value = 'barr' + await nextTick() + expect(root.innerHTML).toBe(`
`) + }) }) diff --git a/packages/runtime-core/src/componentRenderUtils.ts b/packages/runtime-core/src/componentRenderUtils.ts index 6b3be672792..5963f5b303c 100644 --- a/packages/runtime-core/src/componentRenderUtils.ts +++ b/packages/runtime-core/src/componentRenderUtils.ts @@ -90,6 +90,11 @@ export function renderComponentRoot( result.shapeFlag & ShapeFlags.COMPONENT ) { result = cloneVNode(result, attrs) + // If the child root node is a compiler optimized vnode, make sure it + // force update full props to account for the merged attrs. + if (result.dynamicChildren !== null) { + result.patchFlag |= PatchFlags.FULL_PROPS + } } else if (__DEV__ && !accessedAttrs && result.type !== Comment) { warn( `Extraneous non-props attributes (${Object.keys(attrs).join(',')}) ` + @@ -183,7 +188,7 @@ export function shouldUpdateComponent( return hasPropsChanged(prevProps!, nextProps!) } else { if (patchFlag & PatchFlags.CLASS) { - return prevProps!.class === nextProps!.class + return prevProps!.class !== nextProps!.class } if (patchFlag & PatchFlags.STYLE) { return hasPropsChanged(prevProps!.style, nextProps!.style)