vue icon indicating copy to clipboard operation
vue copied to clipboard

It's Impossible to Rename an Inherited Slot

Open rodrigogs opened this issue 3 years ago • 8 comments

Version

2.6.11

Reproduction link

https://github.com/rodrigogs/slots-inheritance-renaming-problem

Steps to reproduce

I created a self-explanatory example in this repository: https://github.com/rodrigogs/slots-inheritance-renaming-problem

But basically, you can't rename inherited slots from a child component. I'm not exactly sure if it should work, so I'm not even sure about it being an issue. But anyway, would be nice to have this working, so I can reuse vuetify component slots more sanely.

What is expected?

Expected to rename the inherited slot by

    <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
      <slot :name="`renamed-${slot}`" v-bind="scope"></slot>
    </template>

What is actually happening?

When using <template v-slot:renamed-slot1> the renamed slot is not replaced

rodrigogs avatar Nov 02 '20 17:11 rodrigogs

This doesn't strike me as something that should be abstracted. I've been been able to successfully "rename" slots by using a wrapper component with manually written slot names. By doing so, you create a stronger connection that is well documented.

<template>
  <some-third-party-component>
    <template #weird-slot-name="props">
      <slot name="sane-name" v-bind="props">Sane Default Slot Content</slot>
    </template>
  </some-third-party-component>
</template>

sirlancelot avatar Nov 02 '20 19:11 sirlancelot

I think the core of your issue though is that you might be mixing the direction the slots need to be named. Take my example, weird-slot-name is a named slot inside some-third-party-component. Additionally, sane-name is the name of the slot in this component. $scopedSlots is a map of slots on this component, not some-third-party-component.

sirlancelot avatar Nov 02 '20 19:11 sirlancelot

In my case I'm creating a simples generic CRUD component, and it would be nice to have access to the slots vuetify components already offers me to customize some specific entity fields.

Thing is... in the case of a data table for instance, I do get a dynamic item.<name> slot for each item property, so I would have to map everything that I want to expose as slots. Why can't I just rename them dynamically with a js expression since it actually works to expose them with their original names?

rodrigogs avatar Nov 03 '20 04:11 rodrigogs

I mean... maybe I'm not doing something that you would recommend at this point. But you have to agree that it would definitely make my life much easier since I'll end up having to map everything dynamically, by basically redoing the work vuetify already does under the hood, or by just using the original slot names and praying to never have a conflicting name.

rodrigogs avatar Nov 03 '20 04:11 rodrigogs

Hi @rodrigogs Is it extremely necessary that you code works with the v-for? it, works just fine by doing the following. It did not work with de v-for though.

`<template>
  <ComponentWithSlots>
    <template v-slot:slot1="scope">
      <slot :name="`renamed-slot1`" :scope="scope"></slot>
    </template>
    <template v-slot:slot2="scope">
      <slot :name="`renamed-slot2`" :scope="scope"></slot>
    </template>
  </ComponentWithSlots>
</template>`

Did not understand why it doesn't works with v-for.

franciscouemura avatar Jan 09 '21 00:01 franciscouemura

Hi @rodrigogs Is it extremely necessary that you code works with the v-for? it, works just fine by doing the following. It did not work with de v-for though.

`<template>
  <ComponentWithSlots>
    <template v-slot:slot1="scope">
      <slot :name="`renamed-slot1`" :scope="scope"></slot>
    </template>
    <template v-slot:slot2="scope">
      <slot :name="`renamed-slot2`" :scope="scope"></slot>
    </template>
  </ComponentWithSlots>
</template>`

Did not understand why it doesn't works with v-for.

I'm using slots like this, but the thing is: Not being able to rename dynamic slots seems like a bug to me. Don't you think?

rodrigogs avatar Jan 09 '21 03:01 rodrigogs

Yeah, I believe it may be a bug. Couldn't make it work dynamically too. We might have to go deeper on this. I've seen another issue that is similar to your problem. I'll leave it here so we have it in mind. Still didn't have the time to read it with full concentration but it seems they might have some common points.

https://github.com/vuejs/vue/issues/11478

franciscouemura avatar Jan 09 '21 14:01 franciscouemura

this worked for me

<template v-for="(_, slot) in $scopedSlots" v-slot:[slotName(slot)]="props"
                  :value="value" :settings="setups">
            <slot :name="slot" :settings="setups" v-bind="{value, refresh, hide, send, reload, update, remove}"/>
</template>
  methods: {
        slotName(slot) {
            return ['title', 'header', 'footer'].indexOf(slot) === -1 ? slot : `modal-${slot}`
        },

mapexpert avatar Mar 17 '22 12:03 mapexpert