]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): ensure inhertied attrs update on optimized child root
authorEvan You <yyx990803@gmail.com>
Fri, 28 Feb 2020 02:51:57 +0000 (21:51 -0500)
committerEvan You <yyx990803@gmail.com>
Fri, 28 Feb 2020 02:51:57 +0000 (21:51 -0500)
fix #677, close #784

packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
packages/runtime-core/src/componentRenderUtils.ts

index 136a0125610663ba81d05844a3565eeb369822df..6ee03207477a0151f0d3e5c18bb852c55210b973 100644 (file)
@@ -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(`<div></div><div class="parent"></div>`)
   })
+
+  // #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(`<div id="foo" class="bar"></div>`)
+
+    id.value = 'fooo'
+    await nextTick()
+    expect(root.innerHTML).toBe(`<div id="fooo" class="bar"></div>`)
+
+    cls.value = 'barr'
+    await nextTick()
+    expect(root.innerHTML).toBe(`<div id="fooo" class="barr"></div>`)
+  })
 })
index 6b3be67279237ed3da9b6596152d8f1f13749dc4..5963f5b303c6608a574703c784b69b614d12de42 100644 (file)
@@ -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)