Przeglądaj źródła

fix(hydration): force hydrate custom element dynamic props

close #7203
close #8038
Evan You 1 rok temu
rodzic
commit
7d473b7721

+ 20 - 0
packages/runtime-core/__tests__/hydration.spec.ts

@@ -1340,6 +1340,26 @@ describe('SSR hydration', () => {
     expect((container.firstChild!.firstChild as any)._value).toBe(true)
   })
 
+  // #7203
+  test('force hydrate custom element with dynamic props', () => {
+    class MyElement extends HTMLElement {
+      foo = ''
+      constructor() {
+        super()
+      }
+    }
+    customElements.define('my-element-7203', MyElement)
+
+    const msg = ref('bar')
+    const container = document.createElement('div')
+    container.innerHTML = '<my-element-7203></my-element-7203>'
+    const app = createSSRApp({
+      render: () => h('my-element-7203', { foo: msg.value }),
+    })
+    app.mount(container)
+    expect((container.firstChild as any).foo).toBe(msg.value)
+  })
+
   // #5728
   test('empty text node in slot', () => {
     const Comp = {

+ 3 - 1
packages/runtime-core/src/hydration.ts

@@ -447,6 +447,7 @@ export function createHydrationFunctions(
           !optimized ||
           patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION)
         ) {
+          const isCustomElement = el.tagName.includes('-')
           for (const key in props) {
             // check hydration mismatch
             if (
@@ -463,7 +464,8 @@ export function createHydrationFunctions(
                 (key.endsWith('value') || key === 'indeterminate')) ||
               (isOn(key) && !isReservedProp(key)) ||
               // force hydrate v-bind with .prop modifiers
-              key[0] === '.'
+              key[0] === '.' ||
+              isCustomElement
             ) {
               patchProp(el, key, null, props[key], undefined, parentComponent)
             }