logaretm / vee-validate

✅ Painless Vue forms
https://vee-validate.logaretm.com/v4
MIT License
10.66k stars 1.25k forks source link

[Feature request] Renderless components #2072

Closed martensm closed 5 years ago

martensm commented 5 years ago

Is your feature request related to a problem? Please describe. Deep styling components wrapped with ValidationObserver or ValidationProvider is more complex as a result of a wrapping element being present in the DOM. I am able to work around this for now but the solution I currently utilize is not ideal.

Describe the solution you'd like Support a property that allows these components to be rendered without the wrapping DOM element.

Describe alternatives you've considered Simply waiting for Vue 3 to natively support fragments should make the wrapping element unnecessary and this property not necessary either.

Additional context portal-vue allows a slim property to be specified for its portal-target component to remove the wrapping element. Can the same thing be done here? In my use case, I know I will always have one root node so this should work.

logaretm commented 5 years ago

The problem lies with the different results returned from scopedSlos(), previously with slot-scope it returns either a VNode or VNode[]. Now with v-slot it is always Node[] which is nicer from a consistency perspective.

Since v-slot can only be applied on template implicitly or explicitly, there is no guarantee to the size of the VNode[], for example, this:

<template v-slot="{ errors }">
  <input v-model="value" type="text">
  <span v-if="errors[0]">{{ errors[0] }}</span>
</template>

Will produce different nodes, and it is impossible to tell whether more nodes will appear or not. On top of that, that looks fine for most users, why would there be an issue with multiple nodes.

That also means that v-slot syntax isn't fully supported out of the box by vee-validate if it is going to do renderless.

I have considered pushing for renderless by default, whenever multiple nodes appear, wrap them with a warning. This, however, causes issues with SSR in cases where initial validation is done and might be confusing to a lot of users and will probably break their styles.

I still prefer the ValidationProvider/Observer to be renderless, with Fragments in Vue 3.x It will be straightforward to use without caveats.

I think your suggestion is very doable at the moment, a slim property is opt-in so anyone who would be using it would be explicitly stating that they have 1 root element. I might go with that in the next release.