<script setup> import { computed } from 'vue'; const model = defineModel(undefined, { required: true }); const $props = defineProps({ prop: { type: Object, required: true, }, components: { type: Object, default: () => {}, }, value: { type: [Object, Number, String, Boolean], default: () => {}, }, }); const componentArray = computed(() => { if (typeof $props.prop === 'object') return [$props.prop]; return $props.prop; }); function mix(toComponent) { const { component, attrs, event } = toComponent; const customComponent = $props.components[component]; return { component: customComponent?.component ?? component, attrs: { ...toValueAttrs(attrs), ...toValueAttrs(customComponent?.attrs), ...toComponent, ...toValueAttrs(customComponent?.forceAttrs), }, event: { ...customComponent?.event, ...event }, }; } function toValueAttrs(attrs) { if (!attrs) return; return typeof attrs == 'function' ? attrs($props.value) : attrs; } </script> <template> <span v-for="toComponent of componentArray" :key="toComponent.name" class="column flex-center fit" > <component v-if="toComponent?.component" :is="mix(toComponent).component" v-bind="mix(toComponent).attrs" v-on="mix(toComponent).event ?? {}" v-model="model" /> </span> </template>