Subscribe on changes!

Fallthrough attributes aren't rendered for renderless components defined with <script setup>, but they are when defined with the explicit Composition API

avatar
Oct 26th 2023

Vue version

3.3.7

Link to minimal reproduction

https://play.vuejs.org/#eNqNU01PwzAM/StWLgVpbQ5wGh3iQ0iAxIeAYy6jNWug+VDijqGp/52kHaNsDHGr7ec8+/l1yU6tzeYNsjHLfeGkJfBIjT0WWiprHMG5URZenFGQZDwGEZ4cCZ3zviFAQ0CobD0lDBFAXsSmSk4Ee/5AwYCHdM7XGDZi/eupmtrs1Rsd+JexU6wKXrAxdJmYC4wxFqwisn7MeVHq0FZiLecu00hcW8VPAoy7RpNUmJZGnRxkB9khL6WnYTpDr9JnZ949uvCIYKMBDQ/JObrUoS7Rofsv7UbbkHqjtEUf2Vuh2yAK+cLoFznbkCSqKWt0d5ak0T+lmda1eb/ucuQaXO9SVFi8/ZJ/9Yt+p3uH3WSD/WnqZkh9+eLxFhfhe11Upmzq1Rl2FB/Qm7qJM/aws0aXYewBrpv2qruw1LMnf7Eg1P5rqThop0aH7+4RDbdr9e9xg9oDFb9MutvTS6igXZk6ujk6OCjvCfor3SBMYG8fJsdQ7SWlnCcjWLYjSC5l3xUpkv0j+OsvyPu3UoVb9m8/AWKjKf8=

Steps to reproduce

  1. Create a renderless component within a script setup block, returning what you would return in a component defined via the explicit Composition API - a function returning h() content.
  2. Render that component, and provide a non-prop attribute to it (e.g. attr="value")

What is expected?

Using the Element tab in your browser's dev tools, the markup related to the renderless component should have the fallthrough attribute being rendered (attr="value")

What is actually happening?

The fallthrough attribute is lost and not rendered. (It is visible in useAttrs() with the child component however?!)

System Info

System:
  OS: macOS 13.5.1
  CPU: (8) arm64 Apple M1 Pro
  Memory: 69.55 MB / 16.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 18.17.0 - ~/.nvm/versions/node/v18.17.0/bin/node
  Yarn: 1.22.19 - /opt/homebrew/bin/yarn
  npm: 9.6.7 - ~/.nvm/versions/node/v18.17.0/bin/npm
Browsers:
  Chrome: 118.0.5993.117
  Safari: 16.6

Any additional comments?

Found while migrating from explicit Composition API to script setup on a renderless component. In a Cypress test a renderless component was used with a fallthrough attribute of data-test-id with a certain value - and the Cypress test did not find that attribute causing the suite / regression test to fail.

I've found that if you define the renderless component returning a 'naked' call to h() instead of a function returning that then the fallthrough attributes are applied - https://play.vuejs.org/#eNqNU9tu2kAQ/ZWRVckgwEZK++JAlLbKQyq1jZo++iFgD3hT70V7cags/3tn1wQMaaI82XM/c2ZPG31WKmkcRlm0MIVmyoJB69RVLhhXUltoQeMGOthoySGm1PjyEPsqudoHktQbvpWP56KQwliwuLOw9B1GceG0RmFBaakymMfjkFejBUYpc7Jo8q2wqJtVPRqNYXkFbS4A2GRCQQjNEoo5hMkSHk77fWhZ90Bp3RQ+zee+9yLtF6JVyLDIVb2ySBZA4XGvsZZPYCrp6hKYKGpXIrQtoek6n7QIWZmfuswj/8kjqBj9r/8i/abUapEe+kbTqGdlxlcqeTRSEKcBf74PmDzK+o28j5jydh5V1iqTpWlRCiorsWaNTgTaVCieXlNaqp2wjOOslPz6IrlIPqYlM3boTtDw2VrLJ4OamuTRdDAmJWeDekZslahRv3fsWdlw9FnoxXg/nUjsiBRr6Cls2PaMEk8uq1H/VJbRUzmhZlXTZb4Fn9UOD7sUFRZ//uN/NLt+pzuNAdlgf7vSW6TL+fDN/Y9wxUOQy9LV+zO8EvyFRtbOY+zTvjhREuxBXkB7Gy7MxPa3udlZFOZ5KQ80sBHywz28UF5b/QiX2B6w+Cyut3Ranaj0KEIvEEMSK3HDBN55axQG+jedwb3VhJvGjI8l/WG/I1VVo7hkTTyFlqQVWiW+bnwJb0ls0XeYcXyhk+4f3BuCng==

However that loses reactivity (as expected), and doesn't match how a renderless component would be defined in the Composition API, which is a transformation of script setup.

Can we also ask that the exact method for defining renderless components using script setup is documented, as the methods used above were only documented on sites like StackOverflow (https://stackoverflow.com/a/70151867).

avatar
Oct 26th 2023

I think this is WAI, the explicit use of h will take over the rendering.

if you want to "fallthrough" you can pass the arg to h

const renderMe = (props) => h('div', props, 'Hi from Comp');

playground

avatar
Oct 26th 2023

Thanks @pikax ! RE:

Can we also ask that the exact method for defining renderless components using script setup is documented, as the methods used above were only documented on sites like StackOverflow (https://stackoverflow.com/a/70151867).

Would there be any issue documenting this somewhere in the Vue docs(at the very least, how to use renderless components in the context of