-
Hi! Wanted to discuss an efficient way of merging custom and primitive props. Recently I started using The problem happens when I make TS definitions of these components with the props over the primitive props like so: <template>
<ToastRoot v-bind="forwarded">
<ToastTitle>{{ title }}</ToastTitle>
<ToastClose />
</ToastRoot>
</template>
<script setup lang="ts">
import type { ToastRootProps, ToastRootEmits } from 'radix-vue';
import {
ToastClose,
ToastRoot,
ToastTitle,
useForwardPropsEmits,
} from 'radix-vue';
interface ToastProps extends ToastRootProps {
title: string;
}
const props = defineProps<ToastProps>();
const emits = defineEmits<ToastRootEmits>();
const forwarded = useForwardPropsEmits(props, emits);
</script> Then I call it like this: <Toast default-open :duration="5000" title="Hello" /> This props merging causes an obvious Vue warning in development mode: I can't really put my mind into which way of separating custom props from primitive props would be the most elegant and efficient. Not sure if I am the only one with this struggle or not. Maybe some new hook from |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Thanks for starting this discussion @VanishMax . We've encountered similar issue too, and we found out that using reactivePick or reactiveOmit can be a good way to solve the headache here. eg: <template>
<ToastRoot v-bind="forwarded">
<ToastTitle>{{ title }}</ToastTitle>
<ToastClose />
</ToastRoot>
</template>
<script setup lang="ts">
import { reactiveOmit } from "@vueuse/core"
import type { ToastRootProps, ToastRootEmits } from 'radix-vue';
import {
ToastClose,
ToastRoot,
ToastTitle,
useForwardPropsEmits,
} from 'radix-vue';
interface ToastProps extends ToastRootProps {
title: string;
}
const props = defineProps<ToastProps>();
const emits = defineEmits<ToastRootEmits>();
const toastRootProps = reactiveOmit(props, 'title') // omit out props.title to prevent it from binding onto `ToastRoot`
const forwarded = useForwardPropsEmits(toastRootProps, emits); // only forwarding the props related to `ToastRoot`
</script> It's not super clean, but it gets the job done for now. I was looking into this Vue discussion for supporting multiple In your case it would come in handy to have 2 |
Beta Was this translation helpful? Give feedback.
Thanks for starting this discussion @VanishMax . We've encountered similar issue too, and we found out that using reactivePick or reactiveOmit can be a good way to solve the headache here.
eg: