sneas / img-comparison-slider

Image comparison slider. Compare images before and after. Supports React, Vue, Angular.
https://img-comparison-slider.sneas.io
MIT License
625 stars 47 forks source link

[vue] slots.default is not a function #146

Open Tofandel opened 1 week ago

Tofandel commented 1 week ago

Using the component using slot="first" conflicts with vue and should instead use real vue slots with the slot attribute, because with the recommended eslint settings (https://eslint.vuejs.org/rules/no-deprecated-slot-attribute.html) the following becomes:

  <img slot="first" src="before.jpg" />
  <img slot="second" src="after.jpg" />
<template #first>
  <img src="before.jpg" />
</template>
<template #second>
  <img src="after.jpg" />
</template>

Which results in no default slot and the error slots.default is not a function

The configuration of this eslint rule does not allow ignoring for a parent component and thus this rule has to be entirely disabled if this lib is used

sneas commented 1 week ago

Hi, as far as I remember, the Vue author came up with this rule because initially, Vue's concept of slots conflicted with standard HTML slots. That's why he deprecated "slot" keyword in the context of Vue components. I didn't look deep into that, since the slots related to img-comparison-slider are the normal HTML slots supported by the HTML standard.

This is the reason for having <!-- eslint-disable --> here https://github.com/sneas/img-comparison-slider/blob/master/packages/vue/README.md#usage just to shut the liter up. It's not very elegant, but it's working and supported by HTML standards.

I understand the solution you suggest looks way better from a Vue developer's standpoint. Someday, img-comparison-slider might fix this; unfortunately, I don't have time to do that.

If you or someone else would like to resolve this issue, then I will be happy to assist.

quetzalsly commented 1 week ago

so how to solve this? the problem is not the eslint error, its google chrome that says slots.default is not a function.

Tofandel commented 1 week ago

@quetzalsly The error is because eslint converts it into a vue slot, but the lib actually uses HTML components with native HTML slots, not vue, so everything should be in the default slot

To solve it I think the best is just to explicitely wrap it in a default slot, which should make eslint unable to transform it and help future you understand what is going on, and also ignore the rule

<template #default>
  <!-- eslint-disable vue/no-deprecated-slot-attribute -->
  <img slot="first" src="before.jpg" />
  <img slot="second" src="after.jpg" />
  <!-- eslint-enable -->
</template>