Compound component with passing props #12955
-
Hi, I hope I used right term in title, if not, Im sorry. My question is: lets say, I have FieldWrapper component. This component has some props (like ID for "for" label, label text, hint, required, disabled, etc). So basically its simple wrapper around actual input. Because it doesnt care about what kind of input you use, you dont need to create component for every input, selector, checkbox, etc. You just wrap them. So basic implementation is like this (just example)
And you will use it like this
What should FieldWrapper internally do:
Is it possible to create it using script setup or I need to use defineComponent with return () => ... ?? Thanks |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 9 replies
-
You can solve this using scoped slots: Playground |
Beta Was this translation helpful? Give feedback.
-
@LadIQe I assume you might be referring to You can achieve this using If you predefined some props, the undefined // FieldWrapper
<script setup lang="ts">
defineProps<{
id: string
label: string
hint?: string
}>()
</script>
<template>
<div class="some-class">
<label :for="id">{{ label }}</label>
- <slot /> // some input
+ <!-- Pass all the attributes from the Parent Component that are not defined as props to the slot element -->
+ <!-- Only forward the not defined props (eg: disabled, required, placeholder...) -->
+ <slot v-bind="$attrs" />
<span v-if="hint">{{ hint }}</span>
</div>
</template> Usage: <FieldWrapper
id="Test id"
label="Test label"
required <!-- 👈 pass `$attrs` into `<slot />` -->
disabled <!-- 👈 pass `$attrs` into `<slot />` -->
hint="This is a hint"
placeholder="Test Placeholder..." <!-- 👈 pass `$attrs` into `<slot />` -->
>
<input type="text" />
</FieldWrapper> If you solve your problem, it's better:) |
Beta Was this translation helpful? Give feedback.
@LadIQe Thanks for providing the repo, I have roughly read the code.
I have written a demo Playground for your reference.
It should be noted that you should not put the
render function
(createElement) directly into the normal function. You need to use thedefineComponent
to define the local component, otherwise it will cause re-rendering every time you input, which will cause the input to lose focus automatically: