Subscribe on changes!

Parent style scope not applied to child component root if root comes from slot content

avatar
Aug 25th 2023

Vue version

3.3.4

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-85scvx?file=src%2FApp.vue,src%2Fcomponents%2FAppLink.vue

Steps to reproduce

Observe the styling of the two links. Only one is correct (has underline).

Use the DOM inspector to compare the two anchors, only one has data-v provided.

What is expected?

Roots of functional components that return only slot content (in this case the native <router-link> with the custom attribute applied) should receive the data-v attribute from the parent.

What is actually happening?

The data-v attribute is not attached to the root, and classes defined and attached in the parent component do not work.

System Info

No response

Any additional comments?

This is the part of <router-link> source code responsible for the difference

return () => {
      const children = slots.default && slots.default(link)
      return props.custom
        ? children
        : h(
            'a',
            {
              'aria-current': link.isExactActive
                ? props.ariaCurrentValue
                : null,
              href: link.href,
              // this would override user added attrs but Vue will still add
              // the listener, so we end up triggering both
              onClick: link.navigate,
              class: elClass.value,
            },
            children
          )
    }
avatar
Aug 29th 2023

I think this is because slot content can be multiple elements, so slot content from a compiled slot is always wrapped in a Fragment vnode - and the renderer doesn't/can't apply attributes to fragment nodes.

For now, I'm not sure wether this strictly needs to be this way for slots.

avatar
Aug 29th 2023

Thanks for the reply.

For us it would be useful to have styling for slots with single root elements, so we can style custom router links (we use custom router links in order to prepend the host name to in-app links).