Skip to content

hydrating vue custom element with key prop will cause unexpected re-mount and lose parent context #11641

@lejunyang

Description

@lejunyang

Vue version

3.4.38

Link to minimal reproduction

https://stackblitz.com/edit/vite-778jll?file=docs%2F.vitepress%2Ftheme%2FLayout.vue

Steps to reproduce

open the console, wait for the build and preview, observe the logs

What is expected?

child element should not be unmounted, inject in child element should work as expected

What is actually happening?

we can see from console's logs, all child elements are unmounted and mounted again, then inject is not working.
image

If we remove key prop from my-test element in Layout.vue, and run npm run test again, we can see they all work as expected.

Hydration performs patchProp for custom element, then we get new props with key and that triggers custom element updating. But old vnode doesn't have a key, which leads to false from isSameVNodeType, unmount happens

    // patching & not same type, unmount old tree
    if (n1 && !isSameVNodeType(n1, n2)) {
      anchor = getNextHostNode(n1)
      unmount(n1, parentComponent, parentSuspense, true)
      n1 = null
    }

Parent component is lost during new mount so inject doesn't work

System Info

No response

Any additional comments?

I can see hydration will finally add key as an attribute for custom element. Adding that in advance when renderToString can avoid unmount. Not sure if it's good solution

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.has workaroundA workaround has been found to avoid the problemscope: custom elementsscope: ssr

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions