core icon indicating copy to clipboard operation
core copied to clipboard

Adding new dynamic named slot

Open Szymon-dziewonski opened this issue 2 months ago • 4 comments

Vue version

3.5.22

Link to minimal reproduction

https://github.com/Szymon-dziewonski/dynamic-slot

Steps to reproduce

I stumbled on a complicated issue where vue cannot create a new named slot with a dynamic name <slot :name="td-${headingPair.key}" while there is children that is component with a default slot and slot itself passes the binding through slot props and binds them to the children. An additional issue is that this is only reproducible on the production build application.

So steps to reproduction are

  1. checkout repo
  2. run yarn
  3. run yarn build and then yarn serve
  4. click add item button in application

Should get in console ( stack trace is Vue only, internals )

Image

and wrong items added by Vue into the DOM

Image

What is expected?

New column should be unshift to the headings and new column should be added. This does not work.

There is also a workaround of this issue created by me in App.vue so you could see it is working correctly in "normal way".
Commented code line 81-103 should be uncommented and line 53-79 commented. This old fashioned way works as expected, same binding passed, same child component passed, but only what differs is not using data coming from dynamically named slot binding props.

What is actually happening?

Vue cannot create named slot with dynamic name on fly and then pass properly every children and bindings

System Info

System:
    OS: macOS 13.2.1
    CPU: (8) arm64 Apple M1
    Memory: 124.05 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 22.17.1 - ~/.nvm/versions/node/v22.17.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v22.17.1/bin/yarn
    npm: 10.9.2 - ~/.nvm/versions/node/v22.17.1/bin/npm
    pnpm: 7.15.0 - ~/.nvm/versions/node/v22.17.1/bin/pnpm
  Browsers:
    Brave Browser: 138.1.80.115
    Chrome: 141.0.7390.55
    Safari: 16.3
  npmPackages:
    vue: ^3.5.22 => 3.5.22

Any additional comments?

No response

Szymon-dziewonski avatar Oct 02 '25 14:10 Szymon-dziewonski

Vue does not support slot nesting like: 

<!-- variant for object table -->
          <template v-for="(headingPair, index) in headingPairs" :key="index">
            <!-- user can target via named slot with heading.key  -->
            <slot
              :name="`th-${headingPair.key}`"
              v-bind="{
                headingPair,
                index,
                bindings: thBindings(headingPair),
              }"
            >
              <!-- general access and then user can filter data -->
              <slot
                name="th"
                v-bind="{
                  headingPair,
                  index,
                  bindings: thBindings(headingPair),
                }"
              >
                <th v-bind="thBindings(headingPair)">
                  {{ headingPair.heading }}
                </th>
              </slot>
            </slot>
          </template>

edison1105 avatar Oct 04 '25 01:10 edison1105

@edison1105 thanks for reply, however, I would say this is not true what you are saying, there is literally no information on their documentation. Additionally, nested slots work, the issue is not connected with nested slots. Just to be sure I removed nested slots and still same issue. At the end, I was working with nested slots for a while, and with vue since beginning, and they are working. Can you please provide some information about the lack of support for nested slots?

Szymon-dziewonski avatar Oct 05 '25 15:10 Szymon-dziewonski

I think you're looking for this https://vuejs.org/guide/components/slots#dynamic-slot-names specifically the

<slot #[`custom${'name')`]>
  <!-- slot content here -->
</slot>

johnazule avatar Oct 20 '25 06:10 johnazule

I think you're looking for this https://vuejs.org/guide/components/slots#dynamic-slot-names specifically the

<slot #[custom${'name')]>

I believe you didnt watched my bug issue reporsitory and code in it, for dynamic slot you can use syntax

<slot :name="`td-${headingPair.key}`"

as well, and this is working when vue does not need to create another named slot with dynamic name

Szymon-dziewonski avatar Oct 20 '25 08:10 Szymon-dziewonski