I have a component that collects data from an API. The data returned from the API is an array containing the details. One of the values in the array is the type of component that should be rendered, all other data is passed to the component. I'm trying to render the correct component based on the value brought back from the database, but unfortunately it doesn't work. I'm new to Vue but it works in vue2 but hope it works in Vue 3 using composition API.
This is the component code I want to replace:
<component :is="question.type" :propdata="question" />
When viewed in a browser, this is what is actually displayed, but without using the SelectInput component:
<selectinput :propdata="question"></selectinput>
SelectInput is a component of my directory and if I hardcode the :is
value it works as expected like this:
<component :is="SelectInput" propdata="question" />
My complete component calls the component
component and swaps components:
<template> <div class="item-group section-wrap"> <div v-bind:key="question.guid" class='component-wrap'> <div class="component-container"> <!-- working --> <component :is="SelectInput" :propData="question" /> <!-- not working --> <component v-bind:is="question.type" :propData="question" /> </div> </div> </div> </template> <script setup> import { defineProps, toRefs } from 'vue'; import SelectInput from "./SelectInput"; import TextareaInput from "./TextareaInput"; const props = defineProps({ question: Object, }); const { question } = toRefs(props); </script>
If your component filenames equal the type specifiers on the object in question, then you can dynamically import them to save some lines of code.
This also leads to better scalability because if you create more types, you don't have to touch this component anymore.
Found that because I was using a
script setting
, the component was not named, so thecomponent
component didn't know which component to render.So I create an object containing the component and a reference to the component:
Another function that takes the component I want to display and links it to the actual component:
Then in the template I call the function and render the correct component:
Complete fixed code:
Not quite sure if this is the correct approach, but it renders the correct component now.