From: Evan You Date: Fri, 28 Feb 2020 02:51:57 +0000 (-0500) Subject: fix(runtime-core): ensure inhertied attrs update on optimized child root X-Git-Tag: v3.0.0-alpha.8~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6810d1402e214a12fa274ff5fb7475bad002d1b1;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-core): ensure inhertied attrs update on optimized child root fix #677, close #784 --- diff --git a/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts b/packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts index 136a012561..6ee0320747 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 6b3be67279..5963f5b303 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)